zudoku 0.0.0-zc17c4c22 → 0.0.0-zd57c18df

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 (232) hide show
  1. package/dist/app/main.js +1 -1
  2. package/dist/app/main.js.map +1 -1
  3. package/dist/config/create-plugin.d.ts +2 -0
  4. package/dist/config/create-plugin.js +55 -0
  5. package/dist/config/create-plugin.js.map +1 -0
  6. package/dist/config/loader.js +2 -2
  7. package/dist/config/loader.js.map +1 -1
  8. package/dist/config/validators/InputNavigationSchema.d.ts +118 -68
  9. package/dist/config/validators/InputNavigationSchema.js +17 -0
  10. package/dist/config/validators/InputNavigationSchema.js.map +1 -1
  11. package/dist/config/validators/NavigationSchema.d.ts +10 -2
  12. package/dist/config/validators/NavigationSchema.js +7 -0
  13. package/dist/config/validators/NavigationSchema.js.map +1 -1
  14. package/dist/config/validators/validate.d.ts +5 -4
  15. package/dist/config/validators/validate.js +2 -0
  16. package/dist/config/validators/validate.js.map +1 -1
  17. package/dist/flat-config.d.ts +12 -0
  18. package/dist/index.d.ts +2 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/lib/components/Bootstrap.js +1 -2
  22. package/dist/lib/components/Bootstrap.js.map +1 -1
  23. package/dist/lib/components/MobileTopNavigation.js +2 -1
  24. package/dist/lib/components/MobileTopNavigation.js.map +1 -1
  25. package/dist/lib/components/Slot.test.js +1 -1
  26. package/dist/lib/components/Slot.test.js.map +1 -1
  27. package/dist/lib/components/TopNavigation.d.ts +7 -1
  28. package/dist/lib/components/TopNavigation.js +7 -2
  29. package/dist/lib/components/TopNavigation.js.map +1 -1
  30. package/dist/lib/components/Zudoku.d.ts +4 -1
  31. package/dist/lib/components/Zudoku.js +4 -7
  32. package/dist/lib/components/Zudoku.js.map +1 -1
  33. package/dist/lib/components/context/ZudokuContext.d.ts +9 -4
  34. package/dist/lib/components/context/ZudokuContext.js +4 -2
  35. package/dist/lib/components/context/ZudokuContext.js.map +1 -1
  36. package/dist/lib/components/context/ZudokuProvider.js +1 -1
  37. package/dist/lib/components/context/ZudokuProvider.js.map +1 -1
  38. package/dist/lib/components/context/ZudokuReactContext.d.ts +11 -0
  39. package/dist/lib/components/context/ZudokuReactContext.js +4 -0
  40. package/dist/lib/components/context/ZudokuReactContext.js.map +1 -0
  41. package/dist/lib/components/navigation/Navigation.js +4 -3
  42. package/dist/lib/components/navigation/Navigation.js.map +1 -1
  43. package/dist/lib/components/navigation/NavigationCategory.js +8 -0
  44. package/dist/lib/components/navigation/NavigationCategory.js.map +1 -1
  45. package/dist/lib/components/navigation/NavigationFilterContext.d.ts +8 -0
  46. package/dist/lib/components/navigation/NavigationFilterContext.js +12 -0
  47. package/dist/lib/components/navigation/NavigationFilterContext.js.map +1 -0
  48. package/dist/lib/components/navigation/NavigationFilterInput.d.ts +3 -0
  49. package/dist/lib/components/navigation/NavigationFilterInput.js +9 -0
  50. package/dist/lib/components/navigation/NavigationFilterInput.js.map +1 -0
  51. package/dist/lib/components/navigation/NavigationItem.js +11 -1
  52. package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
  53. package/dist/lib/components/navigation/utils.d.ts +2 -1
  54. package/dist/lib/components/navigation/utils.js +22 -1
  55. package/dist/lib/components/navigation/utils.js.map +1 -1
  56. package/dist/lib/core/ZudokuContext.d.ts +2 -1
  57. package/dist/lib/core/ZudokuContext.js +3 -1
  58. package/dist/lib/core/ZudokuContext.js.map +1 -1
  59. package/dist/lib/core/__internal.d.ts +1 -0
  60. package/dist/lib/core/__internal.js +2 -0
  61. package/dist/lib/core/__internal.js.map +1 -1
  62. package/dist/lib/core/plugins.d.ts +5 -1
  63. package/dist/lib/core/plugins.js.map +1 -1
  64. package/dist/lib/core/transform-config.d.ts +4 -2
  65. package/dist/lib/core/transform-config.js +33 -13
  66. package/dist/lib/core/transform-config.js.map +1 -1
  67. package/dist/lib/core/transform-config.test.d.ts +1 -0
  68. package/dist/lib/core/transform-config.test.js +83 -0
  69. package/dist/lib/core/transform-config.test.js.map +1 -0
  70. package/dist/lib/errors/ErrorAlert.js +1 -2
  71. package/dist/lib/errors/ErrorAlert.js.map +1 -1
  72. package/dist/lib/hooks/useEvent.test.js +1 -1
  73. package/dist/lib/hooks/useEvent.test.js.map +1 -1
  74. package/dist/lib/plugins/openapi/playground/fileUtils.d.ts +1 -0
  75. package/dist/lib/plugins/openapi/playground/fileUtils.js +3 -0
  76. package/dist/lib/plugins/openapi/playground/fileUtils.js.map +1 -1
  77. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.d.ts +6 -0
  78. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.js +20 -0
  79. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.js.map +1 -0
  80. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +7 -2
  81. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  82. package/dist/lib/ui/Alert.d.ts +3 -2
  83. package/dist/lib/ui/Alert.js +9 -5
  84. package/dist/lib/ui/Alert.js.map +1 -1
  85. package/dist/lib/ui/InputGroup.d.ts +16 -0
  86. package/dist/lib/ui/InputGroup.js +65 -0
  87. package/dist/lib/ui/InputGroup.js.map +1 -0
  88. package/dist/lib/ui/Secret.js +2 -2
  89. package/dist/lib/ui/Secret.js.map +1 -1
  90. package/dist/vite/config.js +5 -2
  91. package/dist/vite/config.js.map +1 -1
  92. package/dist/vite/plugin-config.js +16 -4
  93. package/dist/vite/plugin-config.js.map +1 -1
  94. package/dist/vite/plugin-theme.js +2 -1
  95. package/dist/vite/plugin-theme.js.map +1 -1
  96. package/dist/vite/prerender/prerender.js +3 -1
  97. package/dist/vite/prerender/prerender.js.map +1 -1
  98. package/dist/vite/prerender/worker.js +3 -1
  99. package/dist/vite/prerender/worker.js.map +1 -1
  100. package/lib/{ClaudeLogo-C6q-Xn_l.js → ClaudeLogo-Br8C_vTq.js} +3 -3
  101. package/lib/{ClaudeLogo-C6q-Xn_l.js.map → ClaudeLogo-Br8C_vTq.js.map} +1 -1
  102. package/lib/{HydrationBoundary-CNF2ZV3E.js → HydrationBoundary-CJu4vUlG.js} +6 -6
  103. package/lib/{HydrationBoundary-CNF2ZV3E.js.map → HydrationBoundary-CJu4vUlG.js.map} +1 -1
  104. package/lib/{MdxPage-B1G4W1TK.js → MdxPage-C0QFAsgv.js} +6 -6
  105. package/lib/{MdxPage-B1G4W1TK.js.map → MdxPage-C0QFAsgv.js.map} +1 -1
  106. package/lib/Mermaid-Chx5BPHn.js +104 -0
  107. package/lib/Mermaid-Chx5BPHn.js.map +1 -0
  108. package/lib/{OAuthErrorPage-01Ke086W.js → OAuthErrorPage-CFz_gBFx.js} +11 -10
  109. package/lib/{OAuthErrorPage-01Ke086W.js.map → OAuthErrorPage-CFz_gBFx.js.map} +1 -1
  110. package/lib/{OasProvider-oHPiMJZg.js → OasProvider-BQ60YgAd.js} +3 -3
  111. package/lib/{OasProvider-oHPiMJZg.js.map → OasProvider-BQ60YgAd.js.map} +1 -1
  112. package/lib/{OperationList-CZ4OK8Pm.js → OperationList-D31urxqy.js} +40 -39
  113. package/lib/{OperationList-CZ4OK8Pm.js.map → OperationList-D31urxqy.js.map} +1 -1
  114. package/lib/{RouteGuard-B1lCR0C_.js → RouteGuard-CVs3yvEs.js} +3 -3
  115. package/lib/{RouteGuard-B1lCR0C_.js.map → RouteGuard-CVs3yvEs.js.map} +1 -1
  116. package/lib/{SchemaList-DoQFkJgM.js → SchemaList-CSVFH585.js} +7 -7
  117. package/lib/{SchemaList-DoQFkJgM.js.map → SchemaList-CSVFH585.js.map} +1 -1
  118. package/lib/{SchemaView-D2k6ZJck.js → SchemaView-D4marpgk.js} +3 -3
  119. package/lib/{SchemaView-D2k6ZJck.js.map → SchemaView-D4marpgk.js.map} +1 -1
  120. package/lib/{Secret-BDBqq4p3.js → Secret-DUpgv4V3.js} +92 -72
  121. package/lib/Secret-DUpgv4V3.js.map +1 -0
  122. package/lib/{SignUp-8kDBaLbO.js → SignUp-Dug1jAGC.js} +4 -4
  123. package/lib/{SignUp-8kDBaLbO.js.map → SignUp-Dug1jAGC.js.map} +1 -1
  124. package/lib/{SyntaxHighlight-hZOFnYl0.js → SyntaxHighlight-BMu0b_hF.js} +8 -8
  125. package/lib/{SyntaxHighlight-hZOFnYl0.js.map → SyntaxHighlight-BMu0b_hF.js.map} +1 -1
  126. package/lib/{Toc-qEIii_-W.js → Toc-BiJ2YL0O.js} +2 -2
  127. package/lib/{Toc-qEIii_-W.js.map → Toc-BiJ2YL0O.js.map} +1 -1
  128. package/lib/{Zudoku-DUsdmPME.js → Zudoku-iyiXgWFY.js} +2777 -2622
  129. package/lib/Zudoku-iyiXgWFY.js.map +1 -0
  130. package/lib/ZudokuContext-CYyb_PB_.js +175 -0
  131. package/lib/ZudokuContext-CYyb_PB_.js.map +1 -0
  132. package/lib/ZudokuReactContext-DGJAP1sN.js +222 -0
  133. package/lib/ZudokuReactContext-DGJAP1sN.js.map +1 -0
  134. package/lib/{circular-D9tSKG2c.js → circular-cPOX8BVJ.js} +2 -2
  135. package/lib/{circular-D9tSKG2c.js.map → circular-cPOX8BVJ.js.map} +1 -1
  136. package/lib/{createServer-BprC4n85.js → createServer-SJT25uZH.js} +4 -4
  137. package/lib/{createServer-BprC4n85.js.map → createServer-SJT25uZH.js.map} +1 -1
  138. package/lib/{errors-7hgPDs1h.js → errors-B77S9iOc.js} +2 -2
  139. package/lib/{errors-7hgPDs1h.js.map → errors-B77S9iOc.js.map} +1 -1
  140. package/lib/{firebase-Dwn-2ju-.js → firebase-C7XKRGLf.js} +25 -24
  141. package/lib/{firebase-Dwn-2ju-.js.map → firebase-C7XKRGLf.js.map} +1 -1
  142. package/lib/{hook-ZEd1Es7D.js → hook-Dz_n9SoE.js} +16 -15
  143. package/lib/{hook-ZEd1Es7D.js.map → hook-Dz_n9SoE.js.map} +1 -1
  144. package/lib/{index-Dxdhrp-I.js → index-BDp2MTiq.js} +2 -2
  145. package/lib/{index-Dxdhrp-I.js.map → index-BDp2MTiq.js.map} +1 -1
  146. package/lib/{index-CyIW9rHv.js → index-Bc2mE-53.js} +642 -606
  147. package/lib/index-Bc2mE-53.js.map +1 -0
  148. package/lib/{index.esm-DG4KaDKR.js → index.esm-Cth49JBv.js} +2 -2
  149. package/lib/index.esm-Cth49JBv.js.map +1 -0
  150. package/lib/{mutation-BISOc7OM.js → mutation-B7eFBLZY.js} +2 -2
  151. package/lib/{mutation-BISOc7OM.js.map → mutation-B7eFBLZY.js.map} +1 -1
  152. package/lib/ui/Alert.js +32 -20
  153. package/lib/ui/Alert.js.map +1 -1
  154. package/lib/ui/InputGroup.js +155 -0
  155. package/lib/ui/InputGroup.js.map +1 -0
  156. package/lib/ui/Secret.js +2 -2
  157. package/lib/ui/Secret.js.map +1 -1
  158. package/lib/ui/SyntaxHighlight.js +2 -2
  159. package/lib/{useMutation-CFMGlAMW.js → useMutation-CErliDZ9.js} +5 -5
  160. package/lib/{useMutation-CFMGlAMW.js.map → useMutation-CErliDZ9.js.map} +1 -1
  161. package/lib/{useSuspenseQuery-CSB_rVek.js → useQuery-ht7aWJ3S.js} +432 -446
  162. package/lib/useQuery-ht7aWJ3S.js.map +1 -0
  163. package/lib/useSuspenseQuery-DQH4Bmc2.js +18 -0
  164. package/lib/useSuspenseQuery-DQH4Bmc2.js.map +1 -0
  165. package/lib/zudoku.__internal.js +524 -500
  166. package/lib/zudoku.__internal.js.map +1 -1
  167. package/lib/zudoku.auth-auth0.js +6 -5
  168. package/lib/zudoku.auth-auth0.js.map +1 -1
  169. package/lib/zudoku.auth-azureb2c.js +14 -13
  170. package/lib/zudoku.auth-azureb2c.js.map +1 -1
  171. package/lib/zudoku.auth-clerk.js +2 -2
  172. package/lib/zudoku.auth-firebase.js +4 -4
  173. package/lib/zudoku.auth-openid.js +7 -6
  174. package/lib/zudoku.auth-openid.js.map +1 -1
  175. package/lib/zudoku.auth-supabase.js +4 -4
  176. package/lib/zudoku.components.js +3 -3
  177. package/lib/zudoku.hooks.js +3 -3
  178. package/lib/zudoku.mermaid.js +3 -3
  179. package/lib/zudoku.plugin-api-catalog.js +28 -27
  180. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  181. package/lib/zudoku.plugin-api-keys.js +98 -96
  182. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  183. package/lib/zudoku.plugin-custom-pages.js +1 -1
  184. package/lib/zudoku.plugin-markdown.js +1 -1
  185. package/lib/zudoku.plugin-openapi.js +2 -2
  186. package/lib/zudoku.plugin-search-pagefind.js +19 -18
  187. package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
  188. package/lib/zudoku.plugins.js.map +1 -1
  189. package/lib/zudoku.react-query.js +26 -25
  190. package/lib/zudoku.react-query.js.map +1 -1
  191. package/package.json +9 -3
  192. package/src/app/defaultTheme.css +4 -0
  193. package/src/app/main.css +2 -0
  194. package/src/app/main.tsx +1 -1
  195. package/src/lib/components/Bootstrap.tsx +1 -4
  196. package/src/lib/components/MobileTopNavigation.tsx +13 -8
  197. package/src/lib/components/Slot.test.tsx +1 -1
  198. package/src/lib/components/TopNavigation.tsx +25 -7
  199. package/src/lib/components/Zudoku.tsx +18 -14
  200. package/src/lib/components/context/ZudokuContext.ts +3 -6
  201. package/src/lib/components/context/ZudokuProvider.tsx +1 -1
  202. package/src/lib/components/context/ZudokuReactContext.tsx +17 -0
  203. package/src/lib/components/navigation/Navigation.tsx +4 -3
  204. package/src/lib/components/navigation/NavigationCategory.tsx +9 -0
  205. package/src/lib/components/navigation/NavigationFilterContext.tsx +28 -0
  206. package/src/lib/components/navigation/NavigationFilterInput.tsx +35 -0
  207. package/src/lib/components/navigation/NavigationItem.tsx +17 -1
  208. package/src/lib/components/navigation/utils.ts +32 -1
  209. package/src/lib/core/ZudokuContext.ts +7 -1
  210. package/src/lib/core/__internal.tsx +2 -0
  211. package/src/lib/core/plugins.ts +7 -3
  212. package/src/lib/core/transform-config.test.tsx +99 -0
  213. package/src/lib/core/transform-config.ts +57 -19
  214. package/src/lib/errors/ErrorAlert.tsx +1 -6
  215. package/src/lib/hooks/useEvent.test.tsx +1 -1
  216. package/src/lib/plugins/openapi/playground/fileUtils.ts +4 -0
  217. package/src/lib/plugins/openapi/playground/result-panel/AudioPlayer.tsx +50 -0
  218. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +33 -17
  219. package/src/lib/ui/Alert.tsx +17 -5
  220. package/src/lib/ui/InputGroup.tsx +168 -0
  221. package/src/lib/ui/Secret.tsx +2 -2
  222. package/lib/Mermaid-B1xNo-pf.js +0 -103
  223. package/lib/Mermaid-B1xNo-pf.js.map +0 -1
  224. package/lib/Secret-BDBqq4p3.js.map +0 -1
  225. package/lib/Separator-BXt1LYnm.js +0 -27
  226. package/lib/Separator-BXt1LYnm.js.map +0 -1
  227. package/lib/Zudoku-DUsdmPME.js.map +0 -1
  228. package/lib/ZudokuContext-BBI06sOx.js +0 -387
  229. package/lib/ZudokuContext-BBI06sOx.js.map +0 -1
  230. package/lib/index-CyIW9rHv.js.map +0 -1
  231. package/lib/index.esm-DG4KaDKR.js.map +0 -1
  232. package/lib/useSuspenseQuery-CSB_rVek.js.map +0 -1
@@ -1,4 +1,3 @@
1
- import { SyntaxHighlight } from "zudoku/ui/SyntaxHighlight.js";
2
1
  import { DeveloperHint } from "../components/DeveloperHint.js";
3
2
  import { Heading } from "../components/Heading.js";
4
3
  import { Typography } from "../components/Typography.js";
@@ -22,11 +21,7 @@ export function ErrorAlert({ error }: { error: unknown }) {
22
21
  Error: {message}
23
22
  {hint && <DeveloperHint className="mb-4">{hint}</DeveloperHint>}
24
23
  {stringError && (
25
- <SyntaxHighlight
26
- className="max-h-[400px] [&>pre]:p-4"
27
- language="js"
28
- code={stringError}
29
- />
24
+ <pre className="max-h-[400px] [&>pre]:p-4">{stringError}</pre>
30
25
  )}
31
26
  </Typography>
32
27
  );
@@ -13,7 +13,7 @@ import { useEvent } from "./useEvent.js";
13
13
 
14
14
  const createTestContext = () => {
15
15
  const queryClient = new QueryClient();
16
- const context = new ZudokuContext({}, queryClient);
16
+ const context = new ZudokuContext({}, queryClient, {});
17
17
  const wrapper = ({ children }: PropsWithChildren) => (
18
18
  <QueryClientProvider client={queryClient}>
19
19
  <ZudokuProvider context={context}>{children}</ZudokuProvider>
@@ -4,6 +4,10 @@ export function isBinaryContentType(contentType: string) {
4
4
  );
5
5
  }
6
6
 
7
+ export function isAudioContentType(contentType: string) {
8
+ return /^audio\//i.test(contentType);
9
+ }
10
+
7
11
  export const extractFileName = (
8
12
  headers: Array<[string, string]>,
9
13
  url: string,
@@ -0,0 +1,50 @@
1
+ import { DownloadIcon } from "lucide-react";
2
+ import { useEffect, useState } from "react";
3
+ import { Button } from "zudoku/ui/Button.js";
4
+ import { humanFileSize } from "../../../../util/humanFileSize.js";
5
+
6
+ export const AudioPlayer = ({
7
+ blob,
8
+ fileName,
9
+ size,
10
+ onDownload,
11
+ }: {
12
+ blob: Blob;
13
+ fileName: string;
14
+ size: number;
15
+ onDownload: () => void;
16
+ }) => {
17
+ const [audioUrl, setAudioUrl] = useState<string | null>(null);
18
+
19
+ useEffect(() => {
20
+ const url = URL.createObjectURL(blob);
21
+ setAudioUrl(url);
22
+
23
+ return () => {
24
+ URL.revokeObjectURL(url);
25
+ };
26
+ }, [blob]);
27
+
28
+ if (!audioUrl) {
29
+ return (
30
+ <div className="p-4 text-center">
31
+ <div className="text-sm text-muted-foreground">Loading audio...</div>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ return (
37
+ <div className="p-4 text-center">
38
+ <div className="flex flex-col items-center gap-4">
39
+ {/* biome-ignore lint/a11y/useMediaCaption: API response audio cannot have predefined captions */}
40
+ <audio controls src={audioUrl} className="w-full max-w-md">
41
+ Your browser does not support the audio element.
42
+ </audio>
43
+ <Button onClick={onDownload} className="flex items-center gap-2">
44
+ <DownloadIcon className="h-4 w-4" />
45
+ Download {fileName} ({humanFileSize(size)})
46
+ </Button>
47
+ </div>
48
+ </div>
49
+ );
50
+ };
@@ -32,6 +32,8 @@ import {
32
32
  CollapsibleHeader,
33
33
  CollapsibleHeaderTrigger,
34
34
  } from "../CollapsibleHeader.js";
35
+ import { isAudioContentType } from "../fileUtils.js";
36
+ import { AudioPlayer } from "./AudioPlayer.js";
35
37
  import { convertToTypes } from "./convertToTypes.js";
36
38
 
37
39
  const mimeTypeToLanguage = (mimeType: string) => {
@@ -50,9 +52,14 @@ const mimeTypeToLanguage = (mimeType: string) => {
50
52
  )?.[1];
51
53
  };
52
54
 
55
+ const getContentType = (headers: Array<[string, string]>) => {
56
+ return (
57
+ headers.find(([key]) => key.toLowerCase() === "content-type")?.[1] || ""
58
+ );
59
+ };
60
+
53
61
  const detectLanguage = (headers: Array<[string, string]>) => {
54
- const contentType =
55
- headers.find(([key]) => key.toLowerCase() === "content-type")?.[1] || "";
62
+ const contentType = getContentType(headers);
56
63
  return mimeTypeToLanguage(contentType);
57
64
  };
58
65
 
@@ -293,23 +300,32 @@ export const ResponseTab = ({
293
300
  </div>
294
301
  <div className="flex-1">
295
302
  {isBinary ? (
296
- <div className="p-4 text-center">
297
- <div className="flex flex-col items-center gap-4">
298
- <div className="text-lg font-semibold">Binary Content</div>
299
- <div className="text-sm text-muted-foreground">
300
- This response contains binary data that cannot be displayed as
301
- text.
303
+ blob && isAudioContentType(getContentType(headers)) ? (
304
+ <AudioPlayer
305
+ blob={blob}
306
+ fileName={fileName ?? "audio"}
307
+ size={size}
308
+ onDownload={handleDownload}
309
+ />
310
+ ) : (
311
+ <div className="p-4 text-center">
312
+ <div className="flex flex-col items-center gap-4">
313
+ <div className="text-lg font-semibold">Binary Content</div>
314
+ <div className="text-sm text-muted-foreground">
315
+ This response contains binary data that cannot be displayed as
316
+ text.
317
+ </div>
318
+ <Button
319
+ onClick={handleDownload}
320
+ className="flex items-center gap-2"
321
+ disabled={!blob}
322
+ >
323
+ <DownloadIcon className="h-4 w-4" />
324
+ Download {fileName || "file"} ({humanFileSize(size)})
325
+ </Button>
302
326
  </div>
303
- <Button
304
- onClick={handleDownload}
305
- className="flex items-center gap-2"
306
- disabled={!blob}
307
- >
308
- <DownloadIcon className="h-4 w-4" />
309
- Download {fileName || "file"} ({humanFileSize(size)})
310
- </Button>
311
327
  </div>
312
- </div>
328
+ )
313
329
  ) : (
314
330
  <SyntaxHighlight
315
331
  className="text-xs flex-1"
@@ -3,13 +3,15 @@ import type * as React from "react";
3
3
  import { cn } from "../util/cn.js";
4
4
 
5
5
  const alertVariants = cva(
6
- "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
6
+ "grid gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert",
7
7
  {
8
8
  variants: {
9
9
  variant: {
10
10
  default: "bg-card text-card-foreground",
11
11
  destructive:
12
- "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
12
+ "text-destructive bg-card bg-destructive/5 border-destructive/20 *:data-[slot=alert-description]:text-destructive-foreground *:[svg]:text-current",
13
+ warning:
14
+ "text-warning-foreground bg-card bg-warning/10 border-warning/50 *:data-[slot=alert-description]:text-warning-foreground *:[svg]:text-current",
13
15
  },
14
16
  },
15
17
  defaultVariants: {
@@ -38,7 +40,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
38
40
  <div
39
41
  data-slot="alert-title"
40
42
  className={cn(
41
- "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
43
+ "font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
42
44
  className,
43
45
  )}
44
46
  {...props}
@@ -54,7 +56,7 @@ function AlertDescription({
54
56
  <div
55
57
  data-slot="alert-description"
56
58
  className={cn(
57
- "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
59
+ "text-muted-foreground text-sm text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
58
60
  className,
59
61
  )}
60
62
  {...props}
@@ -62,4 +64,14 @@ function AlertDescription({
62
64
  );
63
65
  }
64
66
 
65
- export { Alert, AlertDescription, AlertTitle };
67
+ function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
68
+ return (
69
+ <div
70
+ data-slot="alert-action"
71
+ className={cn("absolute top-2 right-2", className)}
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+
77
+ export { Alert, AlertTitle, AlertDescription, AlertAction };
@@ -0,0 +1,168 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import type * as React from "react";
3
+ import { cn } from "../util/cn.js";
4
+ import { Button } from "./Button.js";
5
+ import { Input } from "./Input.js";
6
+ import { Textarea } from "./Textarea.js";
7
+
8
+ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
9
+ return (
10
+ <div
11
+ data-slot="input-group"
12
+ role="group"
13
+ className={cn(
14
+ "group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none",
15
+ "h-9 min-w-0 has-[>textarea]:h-auto",
16
+
17
+ // Variants based on alignment.
18
+ "has-[>[data-align=inline-start]]:[&>input]:pl-2",
19
+ "has-[>[data-align=inline-end]]:[&>input]:pr-2",
20
+ "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
21
+ "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
22
+
23
+ // Focus state.
24
+ "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
25
+
26
+ // Error state.
27
+ "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
28
+
29
+ className,
30
+ )}
31
+ {...props}
32
+ />
33
+ );
34
+ }
35
+
36
+ const inputGroupAddonVariants = cva(
37
+ "text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
38
+ {
39
+ variants: {
40
+ align: {
41
+ "inline-start":
42
+ "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
43
+ "inline-end":
44
+ "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
45
+ "block-start":
46
+ "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
47
+ "block-end":
48
+ "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
49
+ },
50
+ },
51
+ defaultVariants: {
52
+ align: "inline-start",
53
+ },
54
+ },
55
+ );
56
+
57
+ function InputGroupAddon({
58
+ className,
59
+ align = "inline-start",
60
+ ...props
61
+ }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
62
+ return (
63
+ // biome-ignore lint/a11y/useKeyWithClickEvents: Focus management
64
+ <div
65
+ role="group"
66
+ data-slot="input-group-addon"
67
+ data-align={align}
68
+ className={cn(inputGroupAddonVariants({ align }), className)}
69
+ onClick={(e) => {
70
+ if ((e.target as HTMLElement).closest("button")) {
71
+ return;
72
+ }
73
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
74
+ }}
75
+ {...props}
76
+ />
77
+ );
78
+ }
79
+
80
+ const inputGroupButtonVariants = cva(
81
+ "text-sm shadow-none flex gap-2 items-center",
82
+ {
83
+ variants: {
84
+ size: {
85
+ xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
86
+ sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
87
+ "icon-xs":
88
+ "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
89
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
90
+ },
91
+ },
92
+ defaultVariants: {
93
+ size: "xs",
94
+ },
95
+ },
96
+ );
97
+
98
+ function InputGroupButton({
99
+ className,
100
+ type = "button",
101
+ variant = "ghost",
102
+ size = "xs",
103
+ ...props
104
+ }: Omit<React.ComponentProps<typeof Button>, "size"> &
105
+ VariantProps<typeof inputGroupButtonVariants>) {
106
+ return (
107
+ <Button
108
+ type={type}
109
+ data-size={size}
110
+ variant={variant}
111
+ className={cn(inputGroupButtonVariants({ size }), className)}
112
+ {...props}
113
+ />
114
+ );
115
+ }
116
+
117
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
118
+ return (
119
+ <span
120
+ className={cn(
121
+ "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
122
+ className,
123
+ )}
124
+ {...props}
125
+ />
126
+ );
127
+ }
128
+
129
+ function InputGroupInput({
130
+ className,
131
+ ...props
132
+ }: React.ComponentProps<"input">) {
133
+ return (
134
+ <Input
135
+ data-slot="input-group-control"
136
+ className={cn(
137
+ "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
138
+ className,
139
+ )}
140
+ {...props}
141
+ />
142
+ );
143
+ }
144
+
145
+ function InputGroupTextarea({
146
+ className,
147
+ ...props
148
+ }: React.ComponentProps<"textarea">) {
149
+ return (
150
+ <Textarea
151
+ data-slot="input-group-control"
152
+ className={cn(
153
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
154
+ className,
155
+ )}
156
+ {...props}
157
+ />
158
+ );
159
+ }
160
+
161
+ export {
162
+ InputGroup,
163
+ InputGroupAddon,
164
+ InputGroupButton,
165
+ InputGroupText,
166
+ InputGroupInput,
167
+ InputGroupTextarea,
168
+ };
@@ -103,7 +103,7 @@ export const Secret = ({
103
103
  setRevealed((prev) => !prev);
104
104
  onReveal?.(!revealed);
105
105
  }}
106
- size="icon"
106
+ size="icon-sm"
107
107
  >
108
108
  {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}
109
109
  </Button>
@@ -114,7 +114,7 @@ export const Secret = ({
114
114
  copyToClipboard(secret);
115
115
  onCopy?.(secret);
116
116
  }}
117
- size="icon"
117
+ size="icon-sm"
118
118
  >
119
119
  {isCopied ? <CheckIcon size={16} /> : <CopyIcon size={16} />}
120
120
  </Button>
@@ -1,103 +0,0 @@
1
- import { j as r } from "./jsx-runtime-BzflLqGi.js";
2
- import { e as f } from "./useSuspenseQuery-CSB_rVek.js";
3
- import { useId as p } from "react";
4
- import { c as g } from "./index-DI5SPFK9.js";
5
- import { c as i } from "./cn-5-Gd1Dss.js";
6
- import { z as v } from "./index-DAWHN3cH.js";
7
- import "./ZudokuContext-BBI06sOx.js";
8
- import { S as x } from "./Spinner-CI6bRyZw.js";
9
- const h = g(
10
- "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
11
- {
12
- variants: {
13
- variant: {
14
- default: "bg-card text-card-foreground",
15
- destructive: "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90"
16
- }
17
- },
18
- defaultVariants: {
19
- variant: "default"
20
- }
21
- }
22
- );
23
- function w({
24
- className: e,
25
- variant: t,
26
- ...a
27
- }) {
28
- return /* @__PURE__ */ r.jsx(
29
- "div",
30
- {
31
- "data-slot": "alert",
32
- role: "alert",
33
- className: i(h({ variant: t }), e),
34
- ...a
35
- }
36
- );
37
- }
38
- function y({ className: e, ...t }) {
39
- return /* @__PURE__ */ r.jsx(
40
- "div",
41
- {
42
- "data-slot": "alert-title",
43
- className: i(
44
- "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
45
- e
46
- ),
47
- ...t
48
- }
49
- );
50
- }
51
- function j({
52
- className: e,
53
- ...t
54
- }) {
55
- return /* @__PURE__ */ r.jsx(
56
- "div",
57
- {
58
- "data-slot": "alert-description",
59
- className: i(
60
- "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
61
- e
62
- ),
63
- ...t
64
- }
65
- );
66
- }
67
- let s = null;
68
- const b = () => (s || (s = import("mermaid").then((e) => e.default).catch((e) => {
69
- throw new Error(
70
- "Mermaid is not installed. Please install it with: npm install mermaid",
71
- { cause: e }
72
- );
73
- })), s), P = ({ chart: e, config: t, ...a }) => {
74
- const d = p(), n = v(), {
75
- data: m,
76
- error: o,
77
- isPending: c
78
- } = f({
79
- queryKey: ["mermaid", e, t, n.resolvedTheme],
80
- queryFn: async () => {
81
- const l = await b();
82
- l.initialize({
83
- theme: n.resolvedTheme === "dark" ? "dark" : "base",
84
- ...t
85
- });
86
- const { svg: u } = await l.render(d, e);
87
- return u;
88
- },
89
- enabled: typeof window < "u",
90
- retry: !1
91
- });
92
- return o ? /* @__PURE__ */ r.jsxs(w, { className: "flex flex-col gap-2", variant: "destructive", children: [
93
- /* @__PURE__ */ r.jsx(y, { children: "Mermaid Error" }),
94
- /* @__PURE__ */ r.jsx(j, { className: "overflow-auto wrap-break-word whitespace-pre-wrap font-mono text-xs", children: o.message })
95
- ] }) : c ? /* @__PURE__ */ r.jsx(x, {}) : /* @__PURE__ */ r.jsx("div", { ...a, dangerouslySetInnerHTML: { __html: m } });
96
- };
97
- export {
98
- w as A,
99
- P as M,
100
- y as a,
101
- j as b
102
- };
103
- //# sourceMappingURL=Mermaid-B1xNo-pf.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Mermaid-B1xNo-pf.js","sources":["../src/lib/ui/Alert.tsx","../src/lib/components/Mermaid.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"../util/cn.js\";\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertDescription, AlertTitle };\n","import { useQuery } from \"@tanstack/react-query\";\nimport type { MermaidConfig } from \"mermaid\";\nimport type { ComponentProps } from \"react\";\nimport { useId } from \"react\";\nimport { Alert, AlertDescription, AlertTitle } from \"zudoku/ui/Alert.js\";\nimport { useTheme } from \"../hooks/index.js\";\nimport { Spinner } from \"./Spinner.js\";\n\nexport type MermaidProps = {\n chart: string;\n config?: MermaidConfig;\n} & ComponentProps<\"div\">;\n\nlet mermaidPromise: Promise<typeof import(\"mermaid\").default> | null = null;\n\nconst loadMermaid = () => {\n if (!mermaidPromise) {\n mermaidPromise = import(\"mermaid\")\n .then((mod) => mod.default)\n .catch((error) => {\n throw new Error(\n \"Mermaid is not installed. Please install it with: npm install mermaid\",\n { cause: error },\n );\n });\n }\n return mermaidPromise;\n};\n\nexport const Mermaid = ({ chart, config, ...props }: MermaidProps) => {\n const id = useId();\n const theme = useTheme();\n\n const {\n data: svg,\n error,\n isPending,\n } = useQuery({\n queryKey: [\"mermaid\", chart, config, theme.resolvedTheme],\n queryFn: async () => {\n const mermaid = await loadMermaid();\n mermaid.initialize({\n theme: theme.resolvedTheme === \"dark\" ? \"dark\" : \"base\",\n ...config,\n });\n\n const { svg } = await mermaid.render(id, chart);\n return svg;\n },\n enabled: typeof window !== \"undefined\",\n retry: false,\n });\n\n if (error)\n return (\n <Alert className=\"flex flex-col gap-2\" variant=\"destructive\">\n <AlertTitle>Mermaid Error</AlertTitle>\n <AlertDescription className=\"overflow-auto wrap-break-word whitespace-pre-wrap font-mono text-xs\">\n {error.message}\n </AlertDescription>\n </Alert>\n );\n\n if (isPending) return <Spinner />;\n\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Mermaid generates valid SVG\n return <div {...props} dangerouslySetInnerHTML={{ __html: svg }} />;\n};\n"],"names":["alertVariants","cva","Alert","className","variant","props","jsx","cn","AlertTitle","AlertDescription","mermaidPromise","loadMermaid","mod","error","Mermaid","chart","config","id","useId","theme","useTheme","svg","isPending","useQuery","mermaid","jsxs","Spinner"],"mappings":";;;;;;;;AAIA,MAAMA,IAAgBC;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,aACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;AAEA,SAASC,EAAM;AAAA,EACb,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,GAAGC;AACL,GAAqE;AACnE,SACEC,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAWC,EAAGP,EAAc,EAAE,SAAAI,EAAA,CAAS,GAAGD,CAAS;AAAA,MAClD,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASG,EAAW,EAAE,WAAAL,GAAW,GAAGE,KAAsC;AACxE,SACEC,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAWC;AAAA,QACT;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASI,EAAiB;AAAA,EACxB,WAAAN;AAAA,EACA,GAAGE;AACL,GAAgC;AAC9B,SACEC,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAWC;AAAA,QACT;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;ACjDA,IAAIK,IAAmE;AAEvE,MAAMC,IAAc,OACbD,MACHA,IAAiB,OAAO,SAAS,EAC9B,KAAK,CAACE,MAAQA,EAAI,OAAO,EACzB,MAAM,CAACC,MAAU;AAChB,QAAM,IAAI;AAAA,IACR;AAAA,IACA,EAAE,OAAOA,EAAA;AAAA,EAAM;AAEnB,CAAC,IAEEH,IAGII,IAAU,CAAC,EAAE,OAAAC,GAAO,QAAAC,GAAQ,GAAGX,QAA0B;AACpE,QAAMY,IAAKC,EAAA,GACLC,IAAQC,EAAA,GAER;AAAA,IACJ,MAAMC;AAAA,IACN,OAAAR;AAAA,IACA,WAAAS;AAAA,EAAA,IACEC,EAAS;AAAA,IACX,UAAU,CAAC,WAAWR,GAAOC,GAAQG,EAAM,aAAa;AAAA,IACxD,SAAS,YAAY;AACnB,YAAMK,IAAU,MAAMb,EAAA;AACtB,MAAAa,EAAQ,WAAW;AAAA,QACjB,OAAOL,EAAM,kBAAkB,SAAS,SAAS;AAAA,QACjD,GAAGH;AAAA,MAAA,CACJ;AAED,YAAM,EAAE,KAAAK,EAAAA,IAAQ,MAAMG,EAAQ,OAAOP,GAAIF,CAAK;AAC9C,aAAOM;AAAAA,IACT;AAAA,IACA,SAAS,OAAO,SAAW;AAAA,IAC3B,OAAO;AAAA,EAAA,CACR;AAED,SAAIR,IAEAY,gBAAAA,EAAAA,KAACvB,GAAA,EAAM,WAAU,uBAAsB,SAAQ,eAC7C,UAAA;AAAA,IAAAI,gBAAAA,EAAAA,IAACE,KAAW,UAAA,gBAAA,CAAa;AAAA,IACzBF,gBAAAA,EAAAA,IAACG,GAAA,EAAiB,WAAU,uEACzB,YAAM,QAAA,CACT;AAAA,EAAA,GACF,IAGAa,IAAkBhB,gBAAAA,MAACoB,GAAA,CAAA,CAAQ,IAGxBpB,gBAAAA,EAAAA,IAAC,SAAK,GAAGD,GAAO,yBAAyB,EAAE,QAAQgB,KAAO;AACnE;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Secret-BDBqq4p3.js","sources":["../src/lib/ui/Select.tsx","../src/lib/ui/Secret.tsx"],"sourcesContent":["import * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"./util.js\";\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"border-input data-placeholder:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"popper\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-32 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width) scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","import { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"../util/cn.js\";\nimport { useCopyToClipboard } from \"../util/useCopyToClipboard.js\";\nimport { Button } from \"./Button.js\";\n\ntype Status = \"active\" | \"expired\" | \"expiring\" | \"revoked\" | \"none\";\n\nexport const SecretText = ({\n secret,\n revealed = false,\n previewChars = 5,\n className,\n}: {\n secret: string;\n revealed?: boolean;\n previewChars?: number;\n className?: string;\n}) => {\n return (\n <span className={cn(\"w-full truncate\", className)}>\n <div\n className={cn(\n \"w-40 inline-block md:w-fit\",\n revealed ? \"\" : \"opacity-50\",\n )}\n >\n {revealed\n ? secret.slice(0, previewChars === 0 ? secret.length : -previewChars)\n : \"•••• \".repeat(\n secret.slice(\n 0,\n previewChars === 0 ? secret.length : -previewChars,\n ).length / 5,\n ) +\n \"•\".repeat(\n secret.slice(\n 0,\n previewChars === 0 ? secret.length : -previewChars,\n ).length % 5,\n )}\n </div>\n {previewChars > 0 && <span>{secret.slice(-previewChars)}</span>}\n </span>\n );\n};\n\nexport const Secret = ({\n secret,\n preview = 5,\n className,\n status,\n onCopy,\n revealed: controlledRevealed,\n onReveal,\n noReveal: disabledReveal,\n}: {\n revealed?: boolean;\n noReveal?: boolean;\n secret: string;\n status?: Status;\n className?: string;\n preview?: number;\n onCopy?: (secret: string) => void;\n onReveal?: (revealed: boolean) => void;\n}) => {\n const previewChars = Math.abs(preview);\n const [isRevealed, setRevealed] = useState(false);\n const [isCopied, copyToClipboard] = useCopyToClipboard();\n\n const revealed = controlledRevealed ?? isRevealed;\n\n return (\n <div\n className={cn(\n \"flex gap-2 items-center text-sm border rounded-md px-1\",\n className,\n )}\n >\n <div className=\"font-mono w-full h-9 items-center flex px-2 text-xs gap-2\">\n {status && (\n <div\n className={cn(\n \"rounded-full shrink-0 w-2 h-2 mr-2\",\n status === \"active\" && \"bg-emerald-400\",\n status === \"expired\" && \"bg-neutral-200\",\n status === \"expiring\" && \"bg-yellow-400\",\n status === \"revoked\" && \"bg-red-400\",\n status === \"none\" && \"opacity-0\",\n )}\n />\n )}\n <SecretText\n secret={secret}\n revealed={revealed}\n previewChars={previewChars}\n />\n </div>\n {disabledReveal !== true && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n setRevealed((prev) => !prev);\n onReveal?.(!revealed);\n }}\n size=\"icon\"\n >\n {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}\n </Button>\n )}\n <Button\n variant=\"ghost\"\n onClick={() => {\n copyToClipboard(secret);\n onCopy?.(secret);\n }}\n size=\"icon\"\n >\n {isCopied ? <CheckIcon size={16} /> : <CopyIcon size={16} />}\n </Button>\n </div>\n );\n};\n"],"names":["Select","props","SelectPrimitive","SelectGroup","SelectValue","SelectTrigger","className","size","children","jsxs","cn","jsx","ChevronDownIcon","SelectContent","position","align","SelectScrollUpButton","SelectScrollDownButton","SelectItem","CheckIcon","ChevronUpIcon","SecretText","secret","revealed","previewChars","Secret","preview","status","onCopy","controlledRevealed","onReveal","disabledReveal","isRevealed","setRevealed","useState","isCopied","copyToClipboard","useCopyToClipboard","Button","prev","EyeOffIcon","EyeIcon","CopyIcon"],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- import { j as i } from "./jsx-runtime-BzflLqGi.js";
2
- import * as n from "@radix-ui/react-separator";
3
- import { c as e } from "./cn-5-Gd1Dss.js";
4
- function p({
5
- className: t,
6
- orientation: a = "horizontal",
7
- decorative: o = !0,
8
- ...r
9
- }) {
10
- return /* @__PURE__ */ i.jsx(
11
- n.Root,
12
- {
13
- "data-slot": "separator",
14
- decorative: o,
15
- orientation: a,
16
- className: e(
17
- "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
18
- t
19
- ),
20
- ...r
21
- }
22
- );
23
- }
24
- export {
25
- p as S
26
- };
27
- //# sourceMappingURL=Separator-BXt1LYnm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Separator-BXt1LYnm.js","sources":["../src/lib/ui/Separator.tsx"],"sourcesContent":["import * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport type * as React from \"react\";\nimport { cn } from \"../util/cn.js\";\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n"],"names":["Separator","className","orientation","decorative","props","jsx","SeparatorPrimitive","cn"],"mappings":";;;AAIA,SAASA,EAAU;AAAA,EACjB,WAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,YAAAC,IAAa;AAAA,EACb,GAAGC;AACL,GAAyD;AACvD,SACEC,gBAAAA,EAAAA;AAAAA,IAACC,EAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,YAAAH;AAAA,MACA,aAAAD;AAAA,MACA,WAAWK;AAAA,QACT;AAAA,QACAN;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV;"}