zudoku 0.64.1 → 0.65.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 (402) hide show
  1. package/dist/app/main.d.ts +91 -1
  2. package/dist/app/main.js +5 -1
  3. package/dist/app/main.js.map +1 -1
  4. package/dist/config/config.d.ts +15 -46
  5. package/dist/config/validators/InputNavigationSchema.d.ts +61 -61
  6. package/dist/config/validators/NavigationSchema.js +2 -4
  7. package/dist/config/validators/NavigationSchema.js.map +1 -1
  8. package/dist/config/validators/ProtectedRoutesSchema.d.ts +1 -1
  9. package/dist/config/validators/validate.d.ts +158 -2
  10. package/dist/config/validators/validate.js +37 -0
  11. package/dist/config/validators/validate.js.map +1 -1
  12. package/dist/config/validators/validate.test.js +43 -0
  13. package/dist/config/validators/validate.test.js.map +1 -1
  14. package/dist/flat-config.d.ts +22 -0
  15. package/dist/lib/auth/issuer.js +3 -0
  16. package/dist/lib/auth/issuer.js.map +1 -1
  17. package/dist/lib/authentication/authentication.d.ts +1 -1
  18. package/dist/lib/authentication/providers/auth0.js +6 -1
  19. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  20. package/dist/lib/authentication/providers/firebase.d.ts +4 -0
  21. package/dist/lib/authentication/providers/firebase.js +215 -0
  22. package/dist/lib/authentication/providers/firebase.js.map +1 -0
  23. package/dist/lib/authentication/providers/supabase.js +1 -6
  24. package/dist/lib/authentication/providers/supabase.js.map +1 -1
  25. package/dist/lib/authentication/ui/ZudokuAuthUi.d.ts +24 -0
  26. package/dist/lib/authentication/ui/ZudokuAuthUi.js +124 -0
  27. package/dist/lib/authentication/ui/ZudokuAuthUi.js.map +1 -0
  28. package/dist/lib/authentication/ui/icons/Apple.d.ts +3 -0
  29. package/dist/lib/authentication/ui/icons/Apple.js +4 -0
  30. package/dist/lib/authentication/ui/icons/Apple.js.map +1 -0
  31. package/dist/lib/authentication/ui/icons/Facebook.d.ts +3 -0
  32. package/dist/lib/authentication/ui/icons/Facebook.js +4 -0
  33. package/dist/lib/authentication/ui/icons/Facebook.js.map +1 -0
  34. package/dist/lib/authentication/ui/icons/Github.d.ts +3 -0
  35. package/dist/lib/authentication/ui/icons/Github.js +4 -0
  36. package/dist/lib/authentication/ui/icons/Github.js.map +1 -0
  37. package/dist/lib/authentication/ui/icons/Google.d.ts +3 -0
  38. package/dist/lib/authentication/ui/icons/Google.js +4 -0
  39. package/dist/lib/authentication/ui/icons/Google.js.map +1 -0
  40. package/dist/lib/authentication/ui/icons/Microsoft.d.ts +3 -0
  41. package/dist/lib/authentication/ui/icons/Microsoft.js +4 -0
  42. package/dist/lib/authentication/ui/icons/Microsoft.js.map +1 -0
  43. package/dist/lib/authentication/ui/icons/X.d.ts +3 -0
  44. package/dist/lib/authentication/ui/icons/X.js +4 -0
  45. package/dist/lib/authentication/ui/icons/X.js.map +1 -0
  46. package/dist/lib/components/Autocomplete.d.ts +3 -1
  47. package/dist/lib/components/Autocomplete.js +6 -2
  48. package/dist/lib/components/Autocomplete.js.map +1 -1
  49. package/dist/lib/components/Heading.d.ts +1 -1
  50. package/dist/lib/components/Layout.js +3 -2
  51. package/dist/lib/components/Layout.js.map +1 -1
  52. package/dist/lib/components/navigation/NavigationItem.js +2 -2
  53. package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
  54. package/dist/lib/core/RouteGuard.js +6 -6
  55. package/dist/lib/core/RouteGuard.js.map +1 -1
  56. package/dist/lib/errors/ErrorAlert.js +1 -1
  57. package/dist/lib/errors/RouterError.d.ts +3 -1
  58. package/dist/lib/errors/RouterError.js +3 -2
  59. package/dist/lib/errors/RouterError.js.map +1 -1
  60. package/dist/lib/oas/parser/index.js +7 -3
  61. package/dist/lib/oas/parser/index.js.map +1 -1
  62. package/dist/lib/plugins/api-keys/ProtectedRoute.js +4 -1
  63. package/dist/lib/plugins/api-keys/ProtectedRoute.js.map +1 -1
  64. package/dist/lib/plugins/openapi/CollapsibleCode.d.ts +1 -0
  65. package/dist/lib/plugins/openapi/CollapsibleCode.js +2 -1
  66. package/dist/lib/plugins/openapi/CollapsibleCode.js.map +1 -1
  67. package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.d.ts +5 -0
  68. package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js +10 -0
  69. package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js.map +1 -0
  70. package/dist/lib/plugins/openapi/OperationList.js +5 -1
  71. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  72. package/dist/lib/plugins/openapi/OperationListItem.d.ts +2 -1
  73. package/dist/lib/plugins/openapi/OperationListItem.js +3 -2
  74. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  75. package/dist/lib/plugins/openapi/ParameterList.js +7 -4
  76. package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
  77. package/dist/lib/plugins/openapi/ParameterListItem.js +17 -6
  78. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  79. package/dist/lib/plugins/openapi/RequestBodySidecarBox.d.ts +9 -2
  80. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +5 -2
  81. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
  82. package/dist/lib/plugins/openapi/ResponsesSidecarBox.d.ts +3 -2
  83. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +25 -4
  84. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
  85. package/dist/lib/plugins/openapi/Sidecar.d.ts +2 -2
  86. package/dist/lib/plugins/openapi/Sidecar.js +53 -26
  87. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  88. package/dist/lib/plugins/openapi/SidecarBox.js +4 -4
  89. package/dist/lib/plugins/openapi/SidecarBox.js.map +1 -1
  90. package/dist/lib/plugins/openapi/SidecarExamples.d.ts +9 -2
  91. package/dist/lib/plugins/openapi/SidecarExamples.js +24 -43
  92. package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
  93. package/dist/lib/plugins/openapi/components/ConstValue.js +1 -1
  94. package/dist/lib/plugins/openapi/components/ConstValue.js.map +1 -1
  95. package/dist/lib/plugins/openapi/components/EnumValues.js +1 -1
  96. package/dist/lib/plugins/openapi/components/EnumValues.js.map +1 -1
  97. package/dist/lib/plugins/openapi/components/NonHighlightedCode.d.ts +4 -0
  98. package/dist/lib/plugins/openapi/components/NonHighlightedCode.js +5 -0
  99. package/dist/lib/plugins/openapi/components/NonHighlightedCode.js.map +1 -0
  100. package/dist/lib/plugins/openapi/components/ResponseContent.js +5 -6
  101. package/dist/lib/plugins/openapi/components/ResponseContent.js.map +1 -1
  102. package/dist/lib/plugins/openapi/interfaces.d.ts +13 -0
  103. package/dist/lib/plugins/openapi/playground/BodyPanel.js +67 -15
  104. package/dist/lib/plugins/openapi/playground/BodyPanel.js.map +1 -1
  105. package/dist/lib/plugins/openapi/playground/CollapsibleHeader.js +2 -2
  106. package/dist/lib/plugins/openapi/playground/CollapsibleHeader.js.map +1 -1
  107. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -1
  108. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  109. package/dist/lib/plugins/openapi/playground/Headers.js +23 -83
  110. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  111. package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +10 -2
  112. package/dist/lib/plugins/openapi/playground/ParamsGrid.js +8 -1
  113. package/dist/lib/plugins/openapi/playground/ParamsGrid.js.map +1 -1
  114. package/dist/lib/plugins/openapi/playground/PathParams.js +2 -3
  115. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  116. package/dist/lib/plugins/openapi/playground/Playground.d.ts +7 -0
  117. package/dist/lib/plugins/openapi/playground/Playground.js +56 -28
  118. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  119. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +3 -2
  120. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  121. package/dist/lib/plugins/openapi/playground/QueryParams.js +16 -40
  122. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  123. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.d.ts +8 -0
  124. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.js +19 -0
  125. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.js.map +1 -0
  126. package/dist/lib/plugins/openapi/playground/request-panel/UrlQueryParams.js +1 -1
  127. package/dist/lib/plugins/openapi/playground/request-panel/UrlQueryParams.js.map +1 -1
  128. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.d.ts +1 -0
  129. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.js +540 -0
  130. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.js.map +1 -0
  131. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.d.ts +40 -0
  132. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.js +205 -0
  133. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.js.map +1 -0
  134. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +2 -2
  135. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  136. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js +1 -1
  137. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js.map +1 -1
  138. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +17 -8
  139. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
  140. package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +1 -1
  141. package/dist/lib/plugins/openapi/schema/SchemaView.js +20 -13
  142. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  143. package/dist/lib/plugins/openapi/schema/UnionView.js +2 -5
  144. package/dist/lib/plugins/openapi/schema/UnionView.js.map +1 -1
  145. package/dist/lib/plugins/openapi/schema/union-helpers.js +0 -1
  146. package/dist/lib/plugins/openapi/schema/union-helpers.js.map +1 -1
  147. package/dist/lib/plugins/openapi/util/generateSchemaExample.js +5 -14
  148. package/dist/lib/plugins/openapi/util/generateSchemaExample.js.map +1 -1
  149. package/dist/lib/ui/Badge.d.ts +3 -3
  150. package/dist/lib/ui/Badge.js +9 -7
  151. package/dist/lib/ui/Badge.js.map +1 -1
  152. package/dist/lib/ui/Button.d.ts +1 -1
  153. package/dist/lib/ui/Button.js +1 -0
  154. package/dist/lib/ui/Button.js.map +1 -1
  155. package/dist/lib/ui/Checkbox.d.ts +2 -2
  156. package/dist/lib/ui/Checkbox.js +4 -4
  157. package/dist/lib/ui/Checkbox.js.map +1 -1
  158. package/dist/lib/ui/CodeBlock.d.ts +0 -1
  159. package/dist/lib/ui/CodeBlock.js +1 -1
  160. package/dist/lib/ui/CodeBlock.js.map +1 -1
  161. package/dist/lib/ui/Collapsible.d.ts +4 -4
  162. package/dist/lib/ui/Collapsible.js +11 -4
  163. package/dist/lib/ui/Collapsible.js.map +1 -1
  164. package/dist/lib/ui/Command.d.ts +3 -3
  165. package/dist/lib/ui/EmbeddedCodeBlock.d.ts +0 -1
  166. package/dist/lib/ui/EmbeddedCodeBlock.js +3 -2
  167. package/dist/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  168. package/dist/lib/ui/Frame.d.ts +8 -0
  169. package/dist/lib/ui/Frame.js +22 -0
  170. package/dist/lib/ui/Frame.js.map +1 -0
  171. package/dist/lib/ui/Item.d.ts +23 -0
  172. package/dist/lib/ui/Item.js +67 -0
  173. package/dist/lib/ui/Item.js.map +1 -0
  174. package/dist/lib/ui/NativeSelect.d.ts +5 -0
  175. package/dist/lib/ui/NativeSelect.js +14 -0
  176. package/dist/lib/ui/NativeSelect.js.map +1 -0
  177. package/dist/lib/ui/Select.d.ts +13 -11
  178. package/dist/lib/ui/Select.js +34 -23
  179. package/dist/lib/ui/Select.js.map +1 -1
  180. package/dist/lib/ui/Separator.d.ts +4 -0
  181. package/dist/lib/ui/Separator.js +8 -0
  182. package/dist/lib/ui/Separator.js.map +1 -0
  183. package/dist/lib/ui/Tooltip.d.ts +7 -7
  184. package/dist/lib/ui/Tooltip.js +16 -10
  185. package/dist/lib/ui/Tooltip.js.map +1 -1
  186. package/dist/lib/util/createVariantComponent.d.ts +5 -2
  187. package/dist/lib/util/createVariantComponent.js +5 -2
  188. package/dist/lib/util/createVariantComponent.js.map +1 -1
  189. package/dist/lib/util/flattenAllOf.d.ts +4 -0
  190. package/dist/lib/util/flattenAllOf.js +65 -0
  191. package/dist/lib/util/flattenAllOf.js.map +1 -0
  192. package/dist/lib/util/flattenAllOf.test.d.ts +1 -0
  193. package/dist/lib/util/flattenAllOf.test.js +532 -0
  194. package/dist/lib/util/flattenAllOf.test.js.map +1 -0
  195. package/dist/lib/util/readFrontmatter.d.ts +6 -0
  196. package/dist/lib/util/readFrontmatter.js +12 -0
  197. package/dist/lib/util/readFrontmatter.js.map +1 -0
  198. package/dist/vite/api/SchemaManager.js +6 -18
  199. package/dist/vite/api/SchemaManager.js.map +1 -1
  200. package/dist/vite/mdx/remark-last-modified.js +57 -3
  201. package/dist/vite/mdx/remark-last-modified.js.map +1 -1
  202. package/dist/vite/plugin-api.js +2 -2
  203. package/dist/vite/plugin-api.js.map +1 -1
  204. package/dist/vite/plugin-frontmatter.js +3 -5
  205. package/dist/vite/plugin-frontmatter.js.map +1 -1
  206. package/dist/vite/plugin-markdown-export.js +3 -4
  207. package/dist/vite/plugin-markdown-export.js.map +1 -1
  208. package/dist/vite/plugin-theme.js +10 -1
  209. package/dist/vite/plugin-theme.js.map +1 -1
  210. package/lib/{Button-DmS4u8Lj.js → Button-B3ucvvQw.js} +7 -6
  211. package/lib/Button-B3ucvvQw.js.map +1 -0
  212. package/lib/{ErrorAlert-DE3Sf66a.js → ErrorAlert-BOVgwTRP.js} +2832 -2857
  213. package/lib/ErrorAlert-BOVgwTRP.js.map +1 -0
  214. package/lib/{MdxPage-DZfeC0QY.js → MdxPage-CBYFyqUs.js} +6 -6
  215. package/lib/{MdxPage-DZfeC0QY.js.map → MdxPage-CBYFyqUs.js.map} +1 -1
  216. package/lib/{OAuthErrorPage-BycMozgn.js → OAuthErrorPage-DlTYnbLO.js} +4 -4
  217. package/lib/{OAuthErrorPage-BycMozgn.js.map → OAuthErrorPage-DlTYnbLO.js.map} +1 -1
  218. package/lib/{OasProvider-1XEOsIiW.js → OasProvider-DIPAQ79S.js} +2 -2
  219. package/lib/{OasProvider-1XEOsIiW.js.map → OasProvider-DIPAQ79S.js.map} +1 -1
  220. package/lib/OperationList-BOTFIfda.js +5688 -0
  221. package/lib/OperationList-BOTFIfda.js.map +1 -0
  222. package/lib/{Pagination-CJszmeSA.js → Pagination-BOZ9Pxcw.js} +2 -2
  223. package/lib/{Pagination-CJszmeSA.js.map → Pagination-BOZ9Pxcw.js.map} +1 -1
  224. package/lib/RouteGuard-Brz95MSt.js +77 -0
  225. package/lib/RouteGuard-Brz95MSt.js.map +1 -0
  226. package/lib/RouterError-DQS_bMwf.js +42 -0
  227. package/lib/RouterError-DQS_bMwf.js.map +1 -0
  228. package/lib/{SchemaList-qOHkDzSz.js → SchemaList-Bu95q_q2.js} +7 -7
  229. package/lib/{SchemaList-qOHkDzSz.js.map → SchemaList-Bu95q_q2.js.map} +1 -1
  230. package/lib/SchemaView-CaxK_HV4.js +586 -0
  231. package/lib/SchemaView-CaxK_HV4.js.map +1 -0
  232. package/lib/Select-DFRCS31-.js +399 -0
  233. package/lib/Select-DFRCS31-.js.map +1 -0
  234. package/lib/{SignUp-6SGx9Yyq.js → SignUp-CfB278ao.js} +2 -2
  235. package/lib/{SignUp-6SGx9Yyq.js.map → SignUp-CfB278ao.js.map} +1 -1
  236. package/lib/{SyntaxHighlight-zvlnSnHB.js → SyntaxHighlight-C19vH0V_.js} +525 -509
  237. package/lib/SyntaxHighlight-C19vH0V_.js.map +1 -0
  238. package/lib/{Toc-Da9yp7lo.js → Toc-DQIqdghO.js} +2 -2
  239. package/lib/{Toc-Da9yp7lo.js.map → Toc-DQIqdghO.js.map} +1 -1
  240. package/lib/{circular-CSSuz-LS.js → circular-B-_VyILZ.js} +6360 -5953
  241. package/lib/circular-B-_VyILZ.js.map +1 -0
  242. package/lib/{createServer-CLbcVLbK.js → createServer-C5lXk4ba.js} +4732 -4273
  243. package/lib/createServer-C5lXk4ba.js.map +1 -0
  244. package/lib/{errors-CuGgh3hf.js → errors-DqoyOKev.js} +2 -2
  245. package/lib/{errors-CuGgh3hf.js.map → errors-DqoyOKev.js.map} +1 -1
  246. package/lib/index-B7yD7ZUk.js +3680 -0
  247. package/lib/index-B7yD7ZUk.js.map +1 -0
  248. package/lib/{index-rYHsvtTo.js → index-BG79m3lF.js} +2 -2
  249. package/lib/{index-rYHsvtTo.js.map → index-BG79m3lF.js.map} +1 -1
  250. package/lib/{index-B1rmok4X.js → index-DHDtI9H5.js} +3 -3
  251. package/lib/{index-B1rmok4X.js.map → index-DHDtI9H5.js.map} +1 -1
  252. package/lib/ui/ActionButton.js +1 -1
  253. package/lib/ui/Badge.js +27 -13
  254. package/lib/ui/Badge.js.map +1 -1
  255. package/lib/ui/Button.js +6 -5
  256. package/lib/ui/Button.js.map +1 -1
  257. package/lib/ui/Checkbox.js +29 -26
  258. package/lib/ui/Checkbox.js.map +1 -1
  259. package/lib/ui/CodeBlock.js +7 -7
  260. package/lib/ui/CodeBlock.js.map +1 -1
  261. package/lib/ui/Collapsible.js +32 -5
  262. package/lib/ui/Collapsible.js.map +1 -1
  263. package/lib/ui/EmbeddedCodeBlock.js +26 -25
  264. package/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  265. package/lib/ui/Frame.js +81 -0
  266. package/lib/ui/Frame.js.map +1 -0
  267. package/lib/ui/Item.js +188 -0
  268. package/lib/ui/Item.js.map +1 -0
  269. package/lib/ui/NativeSelect.js +57 -0
  270. package/lib/ui/NativeSelect.js.map +1 -0
  271. package/lib/ui/Select.js +166 -116
  272. package/lib/ui/Select.js.map +1 -1
  273. package/lib/ui/Separator.js +27 -0
  274. package/lib/ui/Separator.js.map +1 -0
  275. package/lib/ui/SyntaxHighlight.js +1 -1
  276. package/lib/ui/Tabs.js +10 -10
  277. package/lib/ui/Tooltip.js +55 -28
  278. package/lib/ui/Tooltip.js.map +1 -1
  279. package/lib/zudoku.__internal.js +345 -345
  280. package/lib/zudoku.__internal.js.map +1 -1
  281. package/lib/zudoku.auth-auth0.js +7 -7
  282. package/lib/zudoku.auth-auth0.js.map +1 -1
  283. package/lib/zudoku.auth-azureb2c.js +3 -3
  284. package/lib/zudoku.auth-clerk.js +1 -1
  285. package/lib/zudoku.auth-openid.js +3 -3
  286. package/lib/zudoku.auth-supabase.js +30 -33
  287. package/lib/zudoku.auth-supabase.js.map +1 -1
  288. package/lib/zudoku.components.js +2 -2
  289. package/lib/zudoku.plugin-api-catalog.js +3 -3
  290. package/lib/zudoku.plugin-api-keys.js +5 -5
  291. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  292. package/lib/zudoku.plugin-markdown.js +1 -1
  293. package/lib/zudoku.plugin-openapi.js +1 -1
  294. package/lib/zudoku.plugin-search-pagefind.js +2 -2
  295. package/package.json +18 -13
  296. package/src/app/main.css +1 -1
  297. package/src/app/main.tsx +5 -1
  298. package/src/lib/auth/issuer.ts +3 -0
  299. package/src/lib/authentication/authentication.ts +1 -1
  300. package/src/lib/authentication/providers/auth0.tsx +6 -1
  301. package/src/lib/authentication/providers/firebase.tsx +284 -0
  302. package/src/lib/authentication/providers/supabase.tsx +2 -7
  303. package/src/lib/authentication/ui/ZudokuAuthUi.tsx +335 -0
  304. package/src/lib/authentication/ui/icons/Apple.tsx +10 -0
  305. package/src/lib/authentication/ui/icons/Facebook.tsx +15 -0
  306. package/src/lib/authentication/ui/icons/Github.tsx +16 -0
  307. package/src/lib/authentication/ui/icons/Google.tsx +16 -0
  308. package/src/lib/authentication/ui/icons/Microsoft.tsx +12 -0
  309. package/src/lib/authentication/ui/icons/X.tsx +10 -0
  310. package/src/lib/components/Autocomplete.tsx +11 -2
  311. package/src/lib/components/Layout.tsx +3 -2
  312. package/src/lib/components/navigation/NavigationItem.tsx +7 -20
  313. package/src/lib/core/RouteGuard.tsx +8 -8
  314. package/src/lib/errors/ErrorAlert.tsx +1 -1
  315. package/src/lib/errors/RouterError.tsx +7 -2
  316. package/src/lib/oas/parser/index.ts +8 -3
  317. package/src/lib/plugins/api-keys/ProtectedRoute.tsx +11 -7
  318. package/src/lib/plugins/openapi/CollapsibleCode.tsx +5 -3
  319. package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +52 -0
  320. package/src/lib/plugins/openapi/OperationList.tsx +7 -0
  321. package/src/lib/plugins/openapi/OperationListItem.tsx +10 -7
  322. package/src/lib/plugins/openapi/ParameterList.tsx +37 -23
  323. package/src/lib/plugins/openapi/ParameterListItem.tsx +105 -54
  324. package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +48 -7
  325. package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +81 -33
  326. package/src/lib/plugins/openapi/Sidecar.tsx +129 -65
  327. package/src/lib/plugins/openapi/SidecarBox.tsx +26 -4
  328. package/src/lib/plugins/openapi/SidecarExamples.tsx +91 -79
  329. package/src/lib/plugins/openapi/components/ConstValue.tsx +1 -1
  330. package/src/lib/plugins/openapi/components/EnumValues.tsx +2 -2
  331. package/src/lib/plugins/openapi/components/NonHighlightedCode.tsx +22 -0
  332. package/src/lib/plugins/openapi/components/ResponseContent.tsx +63 -53
  333. package/src/lib/plugins/openapi/interfaces.ts +12 -0
  334. package/src/lib/plugins/openapi/playground/BodyPanel.tsx +246 -30
  335. package/src/lib/plugins/openapi/playground/CollapsibleHeader.tsx +10 -6
  336. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +3 -2
  337. package/src/lib/plugins/openapi/playground/Headers.tsx +103 -219
  338. package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +33 -1
  339. package/src/lib/plugins/openapi/playground/PathParams.tsx +26 -34
  340. package/src/lib/plugins/openapi/playground/Playground.tsx +73 -35
  341. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +9 -30
  342. package/src/lib/plugins/openapi/playground/QueryParams.tsx +82 -136
  343. package/src/lib/plugins/openapi/playground/request-panel/MultipartField.tsx +91 -0
  344. package/src/lib/plugins/openapi/playground/request-panel/UrlQueryParams.tsx +1 -1
  345. package/src/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.tsx +872 -0
  346. package/src/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.ts +349 -0
  347. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +2 -6
  348. package/src/lib/plugins/openapi/schema/SchemaExampleAndDefault.tsx +1 -1
  349. package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +89 -55
  350. package/src/lib/plugins/openapi/schema/SchemaView.tsx +82 -53
  351. package/src/lib/plugins/openapi/schema/UnionView.tsx +6 -17
  352. package/src/lib/plugins/openapi/schema/union-helpers.ts +0 -1
  353. package/src/lib/plugins/openapi/util/generateSchemaExample.ts +5 -15
  354. package/src/lib/ui/Badge.tsx +21 -12
  355. package/src/lib/ui/Button.tsx +1 -0
  356. package/src/lib/ui/Checkbox.tsx +23 -24
  357. package/src/lib/ui/CodeBlock.tsx +3 -4
  358. package/src/lib/ui/Collapsible.tsx +26 -4
  359. package/src/lib/ui/EmbeddedCodeBlock.tsx +21 -19
  360. package/src/lib/ui/Frame.tsx +81 -0
  361. package/src/lib/ui/Item.tsx +192 -0
  362. package/src/lib/ui/NativeSelect.tsx +47 -0
  363. package/src/lib/ui/Select.tsx +153 -126
  364. package/src/lib/ui/Separator.tsx +25 -0
  365. package/src/lib/ui/Tooltip.tsx +54 -32
  366. package/src/lib/util/createVariantComponent.tsx +31 -5
  367. package/src/lib/util/flattenAllOf.test.ts +637 -0
  368. package/src/lib/util/flattenAllOf.ts +101 -0
  369. package/src/lib/util/readFrontmatter.ts +13 -0
  370. package/dist/lib/plugins/openapi/playground/InlineInput.d.ts +0 -4
  371. package/dist/lib/plugins/openapi/playground/InlineInput.js +0 -3
  372. package/dist/lib/plugins/openapi/playground/InlineInput.js.map +0 -1
  373. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.d.ts +0 -5
  374. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.js +0 -7
  375. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.js.map +0 -1
  376. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.d.ts +0 -4
  377. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.js +0 -10
  378. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.js.map +0 -1
  379. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.d.ts +0 -5
  380. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.js +0 -16
  381. package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.js.map +0 -1
  382. package/lib/Button-DmS4u8Lj.js.map +0 -1
  383. package/lib/ErrorAlert-DE3Sf66a.js.map +0 -1
  384. package/lib/OperationList-DCJw6wXL.js +0 -5450
  385. package/lib/OperationList-DCJw6wXL.js.map +0 -1
  386. package/lib/RouteGuard-DhU3LRr1.js +0 -81
  387. package/lib/RouteGuard-DhU3LRr1.js.map +0 -1
  388. package/lib/RouterError-VDLnrFqF.js +0 -41
  389. package/lib/RouterError-VDLnrFqF.js.map +0 -1
  390. package/lib/SchemaView-D3hm65cc.js +0 -458
  391. package/lib/SchemaView-D3hm65cc.js.map +0 -1
  392. package/lib/Select-C1DeCqKv.js +0 -372
  393. package/lib/Select-C1DeCqKv.js.map +0 -1
  394. package/lib/SyntaxHighlight-zvlnSnHB.js.map +0 -1
  395. package/lib/circular-CSSuz-LS.js.map +0 -1
  396. package/lib/createServer-CLbcVLbK.js.map +0 -1
  397. package/lib/index-RNAxx6IF.js +0 -3364
  398. package/lib/index-RNAxx6IF.js.map +0 -1
  399. package/src/lib/plugins/openapi/playground/InlineInput.tsx +0 -6
  400. package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.tsx +0 -36
  401. package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.tsx +0 -25
  402. package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.tsx +0 -42
@@ -1,13 +1,8 @@
1
1
  import * as Tabs from "@radix-ui/react-tabs";
2
2
  import { useState } from "react";
3
3
  import { Markdown } from "zudoku/components";
4
- import {
5
- Select,
6
- SelectContent,
7
- SelectItem,
8
- SelectTrigger,
9
- SelectValue,
10
- } from "zudoku/ui/Select.js";
4
+ import { Badge } from "zudoku/ui/Badge.js";
5
+ import { NativeSelect, NativeSelectOption } from "zudoku/ui/NativeSelect.js";
11
6
  import { cn } from "zudoku/ui/util.js";
12
7
  import type { MediaTypeObject } from "../graphql/graphql.js";
13
8
  import { SchemaView } from "../schema/SchemaView.js";
@@ -33,48 +28,61 @@ export const ResponseContent = ({
33
28
  const currentResponse =
34
29
  responses.find((r) => r.statusCode === selectedResponse) ?? responses[0];
35
30
 
31
+ const hideTabs =
32
+ responses.length === 1 && responses.at(0)?.statusCode === "200";
33
+
36
34
  const cardHeader = (
37
- <div className="flex flex-col bg-muted text-muted-foreground">
38
- <div className="flex flex-row items-center gap-2 justify-between px-4 py-2">
39
- <Tabs.List className="flex flex-row font-medium text-sm gap-4">
40
- {responses.map((response) => (
41
- <Tabs.Trigger
42
- key={response.statusCode}
43
- value={response.statusCode}
44
- className={cn(
45
- "py-1 -mx-2 px-2 rounded-md",
46
- "data-[state=active]:dark:ring-1 data-[state=active]:dark:ring-border data-[state=active]:bg-background data-[state=active]:drop-shadow",
47
- "data-[state=active]:font-semibold data-[state=active]:text-foreground",
48
- )}
49
- >
50
- {response.statusCode}
51
- </Tabs.Trigger>
52
- ))}
53
- </Tabs.List>
35
+ <div className="flex flex-col text-muted-foreground">
36
+ <div
37
+ className={cn(
38
+ "flex flex-row items-center gap-2 justify-between",
39
+ !hideTabs && "px-4 py-1.5 border-b",
40
+ )}
41
+ >
42
+ {!hideTabs && (
43
+ <Tabs.List className="flex flex-row font-medium text-sm gap-4">
44
+ {responses.map((response) => (
45
+ <Tabs.Trigger
46
+ key={response.statusCode}
47
+ value={response.statusCode}
48
+ className={cn(
49
+ "py-0.5 h-fit -mx-2 px-2 rounded-md",
50
+ "data-[state=active]:dark:ring-1 data-[state=active]:dark:ring-border data-[state=active]:bg-background data-[state=active]:drop-shadow",
51
+ "data-[state=active]:font-semibold data-[state=active]:text-foreground",
52
+ )}
53
+ >
54
+ {response.statusCode}
55
+ </Tabs.Trigger>
56
+ ))}
57
+ </Tabs.List>
58
+ )}
54
59
  {currentResponse?.content && currentResponse.content.length > 1 && (
55
- <Select
60
+ <NativeSelect
56
61
  value={selectedMediaType}
57
- onValueChange={setSelectedMediaType}
62
+ onChange={(e) => setSelectedMediaType(e.target.value)}
63
+ className="text-xs h-fit py-1 bg-background"
58
64
  >
59
- <SelectTrigger className="h-8 mt-0 max-w-48 text-xs truncate">
60
- <SelectValue placeholder="Select a type" />
61
- </SelectTrigger>
62
- <SelectContent>
63
- {currentResponse.content.map((c) => (
64
- <SelectItem key={c.mediaType} value={c.mediaType}>
65
- {c.mediaType}
66
- </SelectItem>
67
- ))}
68
- </SelectContent>
69
- </Select>
65
+ {currentResponse.content.map((c) => (
66
+ <NativeSelectOption key={c.mediaType} value={c.mediaType}>
67
+ {c.mediaType}
68
+ </NativeSelectOption>
69
+ ))}
70
+ </NativeSelect>
71
+ )}
72
+ </div>
73
+ <div className="p-2 clear-both">
74
+ {hideTabs && (
75
+ <Badge variant="outline" className="float-start me-2">
76
+ {currentResponse?.statusCode}
77
+ </Badge>
78
+ )}
79
+ {currentResponse?.description && (
80
+ <Markdown
81
+ className="text-sm text-muted-foreground max-w-none"
82
+ content={currentResponse.description}
83
+ />
70
84
  )}
71
85
  </div>
72
- {currentResponse?.description && (
73
- <Markdown
74
- className="text-sm border-t px-4 py-2 text-muted-foreground"
75
- content={currentResponse.description}
76
- />
77
- )}
78
86
  </div>
79
87
  );
80
88
 
@@ -88,16 +96,18 @@ export const ResponseContent = ({
88
96
  setSelectedMediaType(newResponse?.content?.[0]?.mediaType ?? "");
89
97
  }}
90
98
  >
91
- {responses.map((response) => {
92
- const content = response.content?.find(
93
- (c) => c.mediaType === selectedMediaType,
94
- );
95
- return (
96
- <Tabs.Content key={response.statusCode} value={response.statusCode}>
97
- <SchemaView schema={content?.schema} cardHeader={cardHeader} />
98
- </Tabs.Content>
99
- );
100
- })}
99
+ {responses.map((response) => (
100
+ <Tabs.Content key={response.statusCode} value={response.statusCode}>
101
+ <SchemaView
102
+ schema={
103
+ response.content?.find(
104
+ (content) => content.mediaType === selectedMediaType,
105
+ )?.schema
106
+ }
107
+ cardHeader={cardHeader}
108
+ />
109
+ </Tabs.Content>
110
+ ))}
101
111
  </Tabs.Root>
102
112
  </div>
103
113
  );
@@ -42,6 +42,16 @@ export type TransformExamplesFn = (options: {
42
42
  type: "request" | "response";
43
43
  }) => Content[];
44
44
 
45
+ export type GenerateCodeSnippetFn = (options: {
46
+ selectedLang: string;
47
+ selectedServer: string;
48
+ context: ZudokuContext;
49
+ auth: AuthState;
50
+ operation: OperationsFragmentFragment;
51
+ // biome-ignore lint/suspicious/noExplicitAny: Allow any type
52
+ example?: any | null;
53
+ }) => string | false;
54
+
45
55
  type BaseOasConfig = {
46
56
  server?: string;
47
57
  path?: string;
@@ -50,12 +60,14 @@ type BaseOasConfig = {
50
60
  schemaImports?: SchemaImports;
51
61
  options?: {
52
62
  examplesLanguage?: string;
63
+ supportedLanguages?: { value: string; label: string }[];
53
64
  disablePlayground?: boolean;
54
65
  disableSidecar?: boolean;
55
66
  showVersionSelect?: "always" | "if-available" | "hide";
56
67
  expandAllTags?: boolean;
57
68
  expandApiInformation?: boolean;
58
69
  transformExamples?: TransformExamplesFn;
70
+ generateCodeSnippet?: GenerateCodeSnippetFn;
59
71
  };
60
72
  };
61
73
 
@@ -1,52 +1,268 @@
1
- import { FileInput } from "lucide-react";
1
+ import {
2
+ ChevronDownIcon,
3
+ FileInput,
4
+ Grid2x2PlusIcon,
5
+ PaperclipIcon,
6
+ ScanTextIcon,
7
+ XIcon,
8
+ } from "lucide-react";
9
+ import { useRef, useState } from "react";
2
10
  import { useFormContext } from "react-hook-form";
11
+ import { Button } from "zudoku/components";
3
12
  import { Collapsible, CollapsibleContent } from "zudoku/ui/Collapsible.js";
13
+ import {
14
+ DropdownMenu,
15
+ DropdownMenuContent,
16
+ DropdownMenuItem,
17
+ DropdownMenuTrigger,
18
+ } from "zudoku/ui/DropdownMenu.js";
4
19
  import { Textarea } from "zudoku/ui/Textarea.js";
5
20
  import { cn } from "../../../util/cn.js";
21
+ import { humanFileSize } from "../../../util/humanFileSize.js";
6
22
  import type { MediaTypeObject } from "../graphql/graphql.js";
7
23
  import {
8
24
  CollapsibleHeader,
9
25
  CollapsibleHeaderTrigger,
10
26
  } from "./CollapsibleHeader.js";
11
27
  import ExamplesDropdown from "./ExamplesDropdown.js";
28
+ import ParamsGrid from "./ParamsGrid.js";
12
29
  import type { PlaygroundForm } from "./Playground.js";
30
+ import { MultipartField } from "./request-panel/MultipartField.js";
31
+ import { useKeyValueFieldManager } from "./request-panel/useKeyValueFieldManager.js";
13
32
 
14
33
  export const BodyPanel = ({ content }: { content?: MediaTypeObject[] }) => {
15
- const { register, setValue, watch } = useFormContext<PlaygroundForm>();
34
+ const { register, setValue, watch, control } =
35
+ useFormContext<PlaygroundForm>();
16
36
  const examples = (content ?? []).flatMap((e) => e.examples);
17
- const headers = watch("headers");
37
+ const [headers, file, bodyMode, body, multipartFormFields] = watch([
38
+ "headers",
39
+ "file",
40
+ "bodyMode",
41
+ "body",
42
+ "multipartFormFields",
43
+ ]);
44
+ const fileInputRef = useRef<HTMLInputElement>(null);
45
+ const [isDragging, setIsDragging] = useState(false);
46
+
47
+ const handleFileSelect = (selectedFile: File | null) => {
48
+ setValue("file", selectedFile);
49
+ if (!selectedFile) return;
50
+ setValue(
51
+ "headers",
52
+ headers.filter(
53
+ (h) => h.name.toLowerCase() !== "content-type" || !h.active,
54
+ ),
55
+ );
56
+ };
57
+
58
+ const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
59
+ const selectedFile = e.target.files?.[0] ?? null;
60
+ handleFileSelect(selectedFile);
61
+ };
62
+
63
+ const handleDragOver = (e: React.DragEvent<HTMLElement>) => {
64
+ e.preventDefault();
65
+ e.stopPropagation();
66
+ setIsDragging(true);
67
+ };
68
+
69
+ const handleDragLeave = (e: React.DragEvent<HTMLElement>) => {
70
+ e.preventDefault();
71
+ e.stopPropagation();
72
+ setIsDragging(false);
73
+ };
74
+
75
+ const handleDrop = (e: React.DragEvent<HTMLElement>) => {
76
+ e.preventDefault();
77
+ e.stopPropagation();
78
+ setIsDragging(false);
79
+
80
+ const droppedFile = e.dataTransfer.files?.[0] ?? null;
81
+ handleFileSelect(droppedFile);
82
+ };
83
+
84
+ const manager = useKeyValueFieldManager<
85
+ PlaygroundForm,
86
+ "multipartFormFields"
87
+ >({
88
+ control,
89
+ name: "multipartFormFields",
90
+ defaultValue: { name: "", value: "", active: false },
91
+ isEmpty: (item) => {
92
+ if (item.value instanceof File) return false;
93
+ return !item.name && !item.value;
94
+ },
95
+ });
96
+
18
97
  return (
19
98
  <Collapsible defaultOpen>
20
- <CollapsibleHeaderTrigger>
99
+ <CollapsibleHeaderTrigger className="items-center">
21
100
  <FileInput size={16} />
22
- <CollapsibleHeader>Body</CollapsibleHeader>
23
- {content && examples.length > 0 ? (
24
- <ExamplesDropdown
25
- examples={content}
26
- onSelect={(example, mediaType) => {
27
- setValue("body", JSON.stringify(example.value, null, 2));
28
- setValue("headers", [
29
- ...headers.filter((h) => h.name !== "Content-Type"),
30
- {
31
- name: "Content-Type",
32
- value: mediaType,
33
- active: true,
34
- },
35
- ]);
36
- }}
101
+ <CollapsibleHeader className="flex items-center justify-between">
102
+ Body
103
+ <div className="flex items-center">
104
+ <DropdownMenu>
105
+ <DropdownMenuTrigger asChild>
106
+ <Button
107
+ variant="ghost"
108
+ size="sm"
109
+ className="hover:bg-accent hover:brightness-95 gap-2"
110
+ >
111
+ {bodyMode === "text" ? (
112
+ <>
113
+ <ScanTextIcon size={14} />
114
+ Text
115
+ </>
116
+ ) : bodyMode === "file" ? (
117
+ <>
118
+ <PaperclipIcon size={14} />
119
+ File
120
+ </>
121
+ ) : (
122
+ <>
123
+ <Grid2x2PlusIcon size={14} />
124
+ Multipart
125
+ </>
126
+ )}
127
+ <ChevronDownIcon size={14} />
128
+ </Button>
129
+ </DropdownMenuTrigger>
130
+ <DropdownMenuContent className="min-w-40">
131
+ <DropdownMenuItem
132
+ onSelect={() => setValue("bodyMode", "text")}
133
+ className="gap-2"
134
+ >
135
+ <ScanTextIcon size={14} />
136
+ <span className="flex-1">Text</span>
137
+ <span>
138
+ {body.length > 0 && (
139
+ <div className="w-1.5 h-1.5 bg-primary rounded-full" />
140
+ )}
141
+ </span>
142
+ </DropdownMenuItem>
143
+ <DropdownMenuItem
144
+ onSelect={() => setValue("bodyMode", "file")}
145
+ className="gap-2"
146
+ >
147
+ <PaperclipIcon size={14} />
148
+ <span className="flex-1">File</span>
149
+ <span>
150
+ {file && (
151
+ <div className="w-1.5 h-1.5 bg-primary rounded-full" />
152
+ )}
153
+ </span>
154
+ </DropdownMenuItem>
155
+ <DropdownMenuItem
156
+ onSelect={() => setValue("bodyMode", "multipart")}
157
+ className="gap-2"
158
+ >
159
+ <Grid2x2PlusIcon size={14} strokeWidth={1.5} />
160
+ <span className="flex-1">Multipart</span>
161
+ <span>
162
+ {multipartFormFields?.some((field) => field.active) && (
163
+ <div className="w-1.5 h-1.5 bg-primary rounded-full" />
164
+ )}
165
+ </span>
166
+ </DropdownMenuItem>
167
+ </DropdownMenuContent>
168
+ </DropdownMenu>
169
+ <input
170
+ ref={fileInputRef}
171
+ type="file"
172
+ className="hidden"
173
+ onChange={handleFileInputChange}
174
+ />
175
+ <div className="w-px mx-1 h-5 bg-border" />
176
+ {content && examples.length > 0 ? (
177
+ <ExamplesDropdown
178
+ examples={content}
179
+ onSelect={(example, mediaType) => {
180
+ setValue("body", JSON.stringify(example.value, null, 2));
181
+ setValue("headers", [
182
+ ...headers.filter((h) => h.name !== "Content-Type"),
183
+ {
184
+ name: "Content-Type",
185
+ value: mediaType,
186
+ active: true,
187
+ },
188
+ ]);
189
+ }}
190
+ />
191
+ ) : (
192
+ <div />
193
+ )}
194
+ </div>
195
+ </CollapsibleHeader>
196
+ </CollapsibleHeaderTrigger>
197
+ <CollapsibleContent className="CollapsibleContent flex flex-col gap-2">
198
+ {bodyMode === "text" && (
199
+ <Textarea
200
+ {...register("body")}
201
+ className={cn(
202
+ "w-full px-4 py-2.5 h-64 font-mono md:text-xs border-none rounded-none focus-visible:ring-0 transition-colors",
203
+ )}
204
+ placeholder="Body content"
37
205
  />
38
- ) : (
39
- <div />
40
206
  )}
41
- </CollapsibleHeaderTrigger>
42
- <CollapsibleContent className="flex flex-col gap-2 ">
43
- <Textarea
44
- {...register("body")}
45
- className={cn(
46
- "w-full p-2 h-64 font-mono md:text-xs border-none rounded-none focus-visible:ring-0",
47
- )}
48
- placeholder="Your body here..."
49
- />
207
+ {bodyMode === "file" && (
208
+ <div
209
+ role="region"
210
+ aria-label="File upload drop zone"
211
+ className={cn(
212
+ "flex flex-col items-center justify-center gap-4 min-h-[300px]",
213
+ )}
214
+ onDragOver={handleDragOver}
215
+ onDragLeave={handleDragLeave}
216
+ onDrop={handleDrop}
217
+ >
218
+ <button
219
+ type="button"
220
+ onClick={() => fileInputRef.current?.click()}
221
+ className={cn(
222
+ "flex items-center justify-center gap-2 rounded-full size-20 p-0 border border-dashed border-muted-foreground/50 hover:bg-accent/75 transition-colors",
223
+ (file || isDragging) && "border-solid",
224
+ isDragging && "bg-accent border-primary",
225
+ )}
226
+ >
227
+ <PaperclipIcon
228
+ className={cn(
229
+ "text-muted-foreground",
230
+ isDragging && "text-primary",
231
+ )}
232
+ size={30}
233
+ />
234
+ </button>
235
+ {file ? (
236
+ <div className="flex items-center justify-between gap-2 px-2 py-1.5 rounded-md border">
237
+ <span className="text-sm truncate" title={file.name}>
238
+ {file.name}{" "}
239
+ <span className="text-muted-foreground">
240
+ ({humanFileSize(file.size)})
241
+ </span>
242
+ </span>
243
+ <Button
244
+ type="button"
245
+ variant="ghost"
246
+ size="icon-xxs"
247
+ onClick={() => handleFileSelect(null)}
248
+ >
249
+ <XIcon size={14} />
250
+ </Button>
251
+ </div>
252
+ ) : (
253
+ <span className="text-lg font-semibold text-muted-foreground">
254
+ Select or drop a file
255
+ </span>
256
+ )}
257
+ </div>
258
+ )}
259
+ {bodyMode === "multipart" && (
260
+ <ParamsGrid>
261
+ {manager.fields.map((field, index) => (
262
+ <MultipartField key={field.id} index={index} manager={manager} />
263
+ ))}
264
+ </ParamsGrid>
265
+ )}
50
266
  </CollapsibleContent>
51
267
  </Collapsible>
52
268
  );
@@ -1,4 +1,4 @@
1
- import { ChevronUpIcon } from "lucide-react";
1
+ import { ChevronsDownUpIcon, ChevronsUpDownIcon } from "lucide-react";
2
2
  import { CollapsibleTrigger } from "zudoku/ui/Collapsible.js";
3
3
  import { cn } from "../../../util/cn.js";
4
4
 
@@ -12,20 +12,24 @@ export const CollapsibleHeaderTrigger = ({
12
12
  return (
13
13
  <div
14
14
  className={cn(
15
- "grid grid-cols-[max-content_1fr_min-content_max-content] items-center gap-2 group bg-muted w-full h-10 ps-4 pe-2 border-b",
15
+ "grid grid-cols-[max-content_1fr_max-content] items-center gap-2 group bg-muted w-full h-10 ps-4 pe-2 border-b",
16
16
  className,
17
17
  )}
18
18
  >
19
19
  {children}
20
20
  <CollapsibleTrigger
21
21
  className={cn(
22
- "flex items-center gap-4 group bg-muted w-full p-2 hover:bg-accent hover:brightness-95 rounded-md",
22
+ "flex items-center gap-4 group bg-muted w-full p-2 hover:bg-accent hover:brightness-95 opacity-75 rounded-md",
23
23
  className,
24
24
  )}
25
25
  >
26
- <ChevronUpIcon
27
- className="group-data-[state=open]:rotate-180 transition-transform shrink-0"
28
- size={16}
26
+ <ChevronsDownUpIcon
27
+ className="group-data-[state=closed]:hidden shrink-0"
28
+ size={14}
29
+ />
30
+ <ChevronsUpDownIcon
31
+ className="group-data-[state=open]:hidden shrink-0"
32
+ size={14}
29
33
  />
30
34
  </CollapsibleTrigger>
31
35
  </div>
@@ -24,9 +24,10 @@ const ExamplesDropdown = ({
24
24
  <Button
25
25
  variant="ghost"
26
26
  size="sm"
27
- className="hover:bg-accent hover:brightness-95"
27
+ className="hover:bg-accent hover:brightness-95 gap-2"
28
28
  >
29
- Use Example <PlusCircleIcon size={16} className="ml-2" />
29
+ Use Example
30
+ <PlusCircleIcon size={14} />
30
31
  </Button>
31
32
  </DropdownMenuTrigger>
32
33
  <DropdownMenuContent className="max-w-72">