zudoku 0.64.2 → 0.65.1

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 (279) 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/validators/InputNavigationSchema.d.ts +16 -16
  5. package/dist/config/validators/NavigationSchema.js +2 -4
  6. package/dist/config/validators/NavigationSchema.js.map +1 -1
  7. package/dist/config/validators/validate.d.ts +53 -1
  8. package/dist/config/validators/validate.js +7 -0
  9. package/dist/config/validators/validate.js.map +1 -1
  10. package/dist/config/validators/validate.test.js +43 -0
  11. package/dist/config/validators/validate.test.js.map +1 -1
  12. package/dist/flat-config.d.ts +6 -0
  13. package/dist/lib/authentication/providers/auth0.js +6 -1
  14. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  15. package/dist/lib/components/Autocomplete.d.ts +3 -1
  16. package/dist/lib/components/Autocomplete.js +6 -2
  17. package/dist/lib/components/Autocomplete.js.map +1 -1
  18. package/dist/lib/components/Layout.js +3 -2
  19. package/dist/lib/components/Layout.js.map +1 -1
  20. package/dist/lib/components/navigation/NavigationItem.js +2 -2
  21. package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
  22. package/dist/lib/errors/ErrorAlert.js +1 -1
  23. package/dist/lib/errors/RouterError.d.ts +3 -1
  24. package/dist/lib/errors/RouterError.js +3 -2
  25. package/dist/lib/errors/RouterError.js.map +1 -1
  26. package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js +1 -1
  27. package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js.map +1 -1
  28. package/dist/lib/plugins/openapi/OperationList.js +2 -1
  29. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  30. package/dist/lib/plugins/openapi/OperationListItem.js +2 -1
  31. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  32. package/dist/lib/plugins/openapi/ParameterList.js +7 -4
  33. package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
  34. package/dist/lib/plugins/openapi/ParameterListItem.js +17 -6
  35. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  36. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +4 -1
  37. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
  38. package/dist/lib/plugins/openapi/ResponsesSidecarBox.d.ts +1 -2
  39. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +15 -6
  40. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
  41. package/dist/lib/plugins/openapi/Sidecar.d.ts +1 -2
  42. package/dist/lib/plugins/openapi/Sidecar.js +39 -15
  43. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  44. package/dist/lib/plugins/openapi/SidecarBox.js +4 -4
  45. package/dist/lib/plugins/openapi/SidecarBox.js.map +1 -1
  46. package/dist/lib/plugins/openapi/SidecarExamples.js +15 -16
  47. package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
  48. package/dist/lib/plugins/openapi/components/ConstValue.js +1 -1
  49. package/dist/lib/plugins/openapi/components/ConstValue.js.map +1 -1
  50. package/dist/lib/plugins/openapi/components/EnumValues.js +1 -1
  51. package/dist/lib/plugins/openapi/components/EnumValues.js.map +1 -1
  52. package/dist/lib/plugins/openapi/components/ResponseContent.js +5 -6
  53. package/dist/lib/plugins/openapi/components/ResponseContent.js.map +1 -1
  54. package/dist/lib/plugins/openapi/interfaces.d.ts +13 -0
  55. package/dist/lib/plugins/openapi/playground/BodyPanel.js +67 -15
  56. package/dist/lib/plugins/openapi/playground/BodyPanel.js.map +1 -1
  57. package/dist/lib/plugins/openapi/playground/CollapsibleHeader.js +2 -2
  58. package/dist/lib/plugins/openapi/playground/CollapsibleHeader.js.map +1 -1
  59. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -1
  60. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  61. package/dist/lib/plugins/openapi/playground/Headers.js +23 -83
  62. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  63. package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +8 -0
  64. package/dist/lib/plugins/openapi/playground/ParamsGrid.js +8 -1
  65. package/dist/lib/plugins/openapi/playground/ParamsGrid.js.map +1 -1
  66. package/dist/lib/plugins/openapi/playground/PathParams.js +2 -3
  67. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  68. package/dist/lib/plugins/openapi/playground/Playground.d.ts +7 -0
  69. package/dist/lib/plugins/openapi/playground/Playground.js +56 -28
  70. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  71. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +3 -2
  72. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  73. package/dist/lib/plugins/openapi/playground/QueryParams.js +16 -40
  74. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  75. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.d.ts +8 -0
  76. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.js +19 -0
  77. package/dist/lib/plugins/openapi/playground/request-panel/MultipartField.js.map +1 -0
  78. package/dist/lib/plugins/openapi/playground/request-panel/UrlQueryParams.js +1 -1
  79. package/dist/lib/plugins/openapi/playground/request-panel/UrlQueryParams.js.map +1 -1
  80. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.d.ts +1 -0
  81. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.js +540 -0
  82. package/dist/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.js.map +1 -0
  83. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.d.ts +40 -0
  84. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.js +205 -0
  85. package/dist/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.js.map +1 -0
  86. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +2 -2
  87. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  88. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js +1 -1
  89. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js.map +1 -1
  90. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +17 -7
  91. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
  92. package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +1 -1
  93. package/dist/lib/plugins/openapi/schema/SchemaView.js +20 -9
  94. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  95. package/dist/lib/plugins/openapi/schema/UnionView.js +2 -5
  96. package/dist/lib/plugins/openapi/schema/UnionView.js.map +1 -1
  97. package/dist/lib/ui/Badge.d.ts +3 -3
  98. package/dist/lib/ui/Badge.js +9 -7
  99. package/dist/lib/ui/Badge.js.map +1 -1
  100. package/dist/lib/ui/Button.d.ts +1 -1
  101. package/dist/lib/ui/Button.js +1 -0
  102. package/dist/lib/ui/Button.js.map +1 -1
  103. package/dist/lib/ui/Checkbox.d.ts +2 -2
  104. package/dist/lib/ui/Checkbox.js +4 -4
  105. package/dist/lib/ui/Checkbox.js.map +1 -1
  106. package/dist/lib/ui/CodeBlock.js +1 -1
  107. package/dist/lib/ui/CodeBlock.js.map +1 -1
  108. package/dist/lib/ui/Collapsible.d.ts +4 -4
  109. package/dist/lib/ui/Collapsible.js +11 -4
  110. package/dist/lib/ui/Collapsible.js.map +1 -1
  111. package/dist/lib/ui/EmbeddedCodeBlock.js +3 -2
  112. package/dist/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  113. package/dist/lib/ui/Frame.d.ts +8 -0
  114. package/dist/lib/ui/Frame.js +22 -0
  115. package/dist/lib/ui/Frame.js.map +1 -0
  116. package/dist/lib/ui/Item.d.ts +23 -0
  117. package/dist/lib/ui/Item.js +67 -0
  118. package/dist/lib/ui/Item.js.map +1 -0
  119. package/dist/lib/ui/NativeSelect.d.ts +5 -0
  120. package/dist/lib/ui/NativeSelect.js +14 -0
  121. package/dist/lib/ui/NativeSelect.js.map +1 -0
  122. package/dist/lib/ui/Select.d.ts +13 -11
  123. package/dist/lib/ui/Select.js +34 -23
  124. package/dist/lib/ui/Select.js.map +1 -1
  125. package/dist/lib/util/readFrontmatter.d.ts +6 -0
  126. package/dist/lib/util/readFrontmatter.js +12 -0
  127. package/dist/lib/util/readFrontmatter.js.map +1 -0
  128. package/dist/vite/mdx/remark-last-modified.js +57 -3
  129. package/dist/vite/mdx/remark-last-modified.js.map +1 -1
  130. package/dist/vite/plugin-api.js +2 -2
  131. package/dist/vite/plugin-api.js.map +1 -1
  132. package/dist/vite/plugin-frontmatter.js +3 -5
  133. package/dist/vite/plugin-frontmatter.js.map +1 -1
  134. package/dist/vite/plugin-markdown-export.js +3 -4
  135. package/dist/vite/plugin-markdown-export.js.map +1 -1
  136. package/lib/{Button-DmS4u8Lj.js → Button-B3ucvvQw.js} +7 -6
  137. package/lib/Button-B3ucvvQw.js.map +1 -0
  138. package/lib/{ErrorAlert--3alJ_-b.js → ErrorAlert-D5LKLFOd.js} +1100 -1112
  139. package/lib/ErrorAlert-D5LKLFOd.js.map +1 -0
  140. package/lib/{MdxPage-Bpa9tL63.js → MdxPage-hOCN-u-L.js} +6 -6
  141. package/lib/{MdxPage-Bpa9tL63.js.map → MdxPage-hOCN-u-L.js.map} +1 -1
  142. package/lib/{OAuthErrorPage-B79J86Fo.js → OAuthErrorPage-oXnxcJg4.js} +4 -4
  143. package/lib/{OAuthErrorPage-B79J86Fo.js.map → OAuthErrorPage-oXnxcJg4.js.map} +1 -1
  144. package/lib/{OasProvider-jr0oDSFy.js → OasProvider-BuBeRIHB.js} +2 -2
  145. package/lib/{OasProvider-jr0oDSFy.js.map → OasProvider-BuBeRIHB.js.map} +1 -1
  146. package/lib/{OperationList-DLEAg4qw.js → OperationList-Cx8TGKhB.js} +2053 -1830
  147. package/lib/OperationList-Cx8TGKhB.js.map +1 -0
  148. package/lib/{Pagination-H2HW9-Er.js → Pagination-lLSoHnxa.js} +2 -2
  149. package/lib/{Pagination-H2HW9-Er.js.map → Pagination-lLSoHnxa.js.map} +1 -1
  150. package/lib/{RouteGuard-CjzxosTf.js → RouteGuard-Brz95MSt.js} +2 -2
  151. package/lib/{RouteGuard-CjzxosTf.js.map → RouteGuard-Brz95MSt.js.map} +1 -1
  152. package/lib/RouterError-VGZB_wg4.js +42 -0
  153. package/lib/RouterError-VGZB_wg4.js.map +1 -0
  154. package/lib/{SchemaList-CSDSazqV.js → SchemaList-rBWXYJEb.js} +7 -7
  155. package/lib/{SchemaList-CSDSazqV.js.map → SchemaList-rBWXYJEb.js.map} +1 -1
  156. package/lib/SchemaView-jouS_xvc.js +586 -0
  157. package/lib/SchemaView-jouS_xvc.js.map +1 -0
  158. package/lib/Select-DFRCS31-.js +399 -0
  159. package/lib/Select-DFRCS31-.js.map +1 -0
  160. package/lib/{SignUp-Fycafbyg.js → SignUp-D2mmQOkg.js} +2 -2
  161. package/lib/{SignUp-Fycafbyg.js.map → SignUp-D2mmQOkg.js.map} +1 -1
  162. package/lib/{Toc-ChkOg2UU.js → Toc-CBWfFCVf.js} +2 -2
  163. package/lib/{Toc-ChkOg2UU.js.map → Toc-CBWfFCVf.js.map} +1 -1
  164. package/lib/{circular-DGfd8SGc.js → circular-CGkbVs2O.js} +6360 -5953
  165. package/lib/circular-CGkbVs2O.js.map +1 -0
  166. package/lib/{createServer-DGD8hEzT.js → createServer-CcV_75PW.js} +770 -735
  167. package/lib/createServer-CcV_75PW.js.map +1 -0
  168. package/lib/{errors-BTpjwHS6.js → errors-D7xzOd8X.js} +2 -2
  169. package/lib/{errors-BTpjwHS6.js.map → errors-D7xzOd8X.js.map} +1 -1
  170. package/lib/{index-Bvas0H4x.js → index-CF7_erXq.js} +2 -2
  171. package/lib/{index-Bvas0H4x.js.map → index-CF7_erXq.js.map} +1 -1
  172. package/lib/{index-FNRZUtwo.js → index-CPws05Tb.js} +3 -3
  173. package/lib/{index-FNRZUtwo.js.map → index-CPws05Tb.js.map} +1 -1
  174. package/lib/index-I4zC7Yht.js +3680 -0
  175. package/lib/index-I4zC7Yht.js.map +1 -0
  176. package/lib/ui/ActionButton.js +1 -1
  177. package/lib/ui/Badge.js +27 -13
  178. package/lib/ui/Badge.js.map +1 -1
  179. package/lib/ui/Button.js +6 -5
  180. package/lib/ui/Button.js.map +1 -1
  181. package/lib/ui/Checkbox.js +29 -26
  182. package/lib/ui/Checkbox.js.map +1 -1
  183. package/lib/ui/CodeBlock.js +7 -7
  184. package/lib/ui/CodeBlock.js.map +1 -1
  185. package/lib/ui/Collapsible.js +32 -5
  186. package/lib/ui/Collapsible.js.map +1 -1
  187. package/lib/ui/EmbeddedCodeBlock.js +19 -18
  188. package/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  189. package/lib/ui/Frame.js +81 -0
  190. package/lib/ui/Frame.js.map +1 -0
  191. package/lib/ui/Item.js +188 -0
  192. package/lib/ui/Item.js.map +1 -0
  193. package/lib/ui/NativeSelect.js +57 -0
  194. package/lib/ui/NativeSelect.js.map +1 -0
  195. package/lib/ui/Select.js +166 -116
  196. package/lib/ui/Select.js.map +1 -1
  197. package/lib/ui/Tabs.js +10 -10
  198. package/lib/zudoku.__internal.js +345 -345
  199. package/lib/zudoku.__internal.js.map +1 -1
  200. package/lib/zudoku.auth-auth0.js +7 -7
  201. package/lib/zudoku.auth-auth0.js.map +1 -1
  202. package/lib/zudoku.auth-azureb2c.js +3 -3
  203. package/lib/zudoku.auth-clerk.js +1 -1
  204. package/lib/zudoku.auth-openid.js +3 -3
  205. package/lib/zudoku.auth-supabase.js +3 -3
  206. package/lib/zudoku.components.js +2 -2
  207. package/lib/zudoku.plugin-api-catalog.js +3 -3
  208. package/lib/zudoku.plugin-api-keys.js +4 -4
  209. package/lib/zudoku.plugin-markdown.js +1 -1
  210. package/lib/zudoku.plugin-openapi.js +1 -1
  211. package/lib/zudoku.plugin-search-pagefind.js +2 -2
  212. package/package.json +4 -4
  213. package/src/app/main.tsx +5 -1
  214. package/src/lib/authentication/providers/auth0.tsx +6 -1
  215. package/src/lib/components/Autocomplete.tsx +11 -2
  216. package/src/lib/components/Layout.tsx +3 -2
  217. package/src/lib/components/navigation/NavigationItem.tsx +7 -20
  218. package/src/lib/errors/ErrorAlert.tsx +1 -1
  219. package/src/lib/errors/RouterError.tsx +7 -2
  220. package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +2 -2
  221. package/src/lib/plugins/openapi/OperationList.tsx +3 -1
  222. package/src/lib/plugins/openapi/OperationListItem.tsx +7 -7
  223. package/src/lib/plugins/openapi/ParameterList.tsx +37 -23
  224. package/src/lib/plugins/openapi/ParameterListItem.tsx +105 -54
  225. package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +36 -13
  226. package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +67 -44
  227. package/src/lib/plugins/openapi/Sidecar.tsx +84 -41
  228. package/src/lib/plugins/openapi/SidecarBox.tsx +26 -4
  229. package/src/lib/plugins/openapi/SidecarExamples.tsx +59 -37
  230. package/src/lib/plugins/openapi/components/ConstValue.tsx +1 -1
  231. package/src/lib/plugins/openapi/components/EnumValues.tsx +2 -2
  232. package/src/lib/plugins/openapi/components/ResponseContent.tsx +63 -53
  233. package/src/lib/plugins/openapi/interfaces.ts +12 -0
  234. package/src/lib/plugins/openapi/playground/BodyPanel.tsx +246 -30
  235. package/src/lib/plugins/openapi/playground/CollapsibleHeader.tsx +10 -6
  236. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +3 -2
  237. package/src/lib/plugins/openapi/playground/Headers.tsx +103 -219
  238. package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +33 -1
  239. package/src/lib/plugins/openapi/playground/PathParams.tsx +26 -34
  240. package/src/lib/plugins/openapi/playground/Playground.tsx +73 -35
  241. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +9 -30
  242. package/src/lib/plugins/openapi/playground/QueryParams.tsx +82 -136
  243. package/src/lib/plugins/openapi/playground/request-panel/MultipartField.tsx +91 -0
  244. package/src/lib/plugins/openapi/playground/request-panel/UrlQueryParams.tsx +1 -1
  245. package/src/lib/plugins/openapi/playground/request-panel/fieldManager/useKeyValueFieldManager.test.tsx +872 -0
  246. package/src/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.ts +349 -0
  247. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +2 -6
  248. package/src/lib/plugins/openapi/schema/SchemaExampleAndDefault.tsx +1 -1
  249. package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +89 -52
  250. package/src/lib/plugins/openapi/schema/SchemaView.tsx +82 -48
  251. package/src/lib/plugins/openapi/schema/UnionView.tsx +6 -17
  252. package/src/lib/ui/Badge.tsx +21 -12
  253. package/src/lib/ui/Button.tsx +1 -0
  254. package/src/lib/ui/Checkbox.tsx +23 -24
  255. package/src/lib/ui/CodeBlock.tsx +3 -3
  256. package/src/lib/ui/Collapsible.tsx +26 -4
  257. package/src/lib/ui/EmbeddedCodeBlock.tsx +21 -18
  258. package/src/lib/ui/Frame.tsx +81 -0
  259. package/src/lib/ui/Item.tsx +192 -0
  260. package/src/lib/ui/NativeSelect.tsx +47 -0
  261. package/src/lib/ui/Select.tsx +153 -126
  262. package/src/lib/util/readFrontmatter.ts +13 -0
  263. package/dist/lib/plugins/openapi/playground/InlineInput.d.ts +0 -4
  264. package/dist/lib/plugins/openapi/playground/InlineInput.js +0 -3
  265. package/dist/lib/plugins/openapi/playground/InlineInput.js.map +0 -1
  266. package/lib/Button-DmS4u8Lj.js.map +0 -1
  267. package/lib/ErrorAlert--3alJ_-b.js.map +0 -1
  268. package/lib/OperationList-DLEAg4qw.js.map +0 -1
  269. package/lib/RouterError-DZS2d6Sc.js +0 -41
  270. package/lib/RouterError-DZS2d6Sc.js.map +0 -1
  271. package/lib/SchemaView-DJiBd0_5.js +0 -397
  272. package/lib/SchemaView-DJiBd0_5.js.map +0 -1
  273. package/lib/Select-C1DeCqKv.js +0 -372
  274. package/lib/Select-C1DeCqKv.js.map +0 -1
  275. package/lib/circular-DGfd8SGc.js.map +0 -1
  276. package/lib/createServer-DGD8hEzT.js.map +0 -1
  277. package/lib/index-DP1xZgfJ.js +0 -3364
  278. package/lib/index-DP1xZgfJ.js.map +0 -1
  279. package/src/lib/plugins/openapi/playground/InlineInput.tsx +0 -6
@@ -4,9 +4,10 @@ import { useState } from "react";
4
4
  import { Markdown } from "../../components/Markdown.js";
5
5
  import type { SchemaObject } from "../../oas/graphql/index.js";
6
6
  import { Button } from "../../ui/Button.js";
7
+ import { Item, ItemActions, ItemContent, ItemTitle } from "../../ui/Item.js";
8
+ import { cn } from "../../util/cn.js";
7
9
  import { ColorizedParam } from "./ColorizedParam.js";
8
10
  import { EnumValues } from "./components/EnumValues.js";
9
- import { SelectOnClick } from "./components/SelectOnClick.js";
10
11
  import type { ParameterItem } from "./graphql/graphql.js";
11
12
  import type { ParameterGroup } from "./OperationListItem.js";
12
13
  import { ParamInfos } from "./ParamInfos.js";
@@ -35,75 +36,125 @@ export const ParameterListItem = ({
35
36
  const paramSchema = getParameterSchema(parameter);
36
37
  const [isOpen, setIsOpen] = useState(false);
37
38
 
39
+ const isCollapsible =
40
+ paramSchema.type === "object" ||
41
+ (isArrayType(paramSchema) &&
42
+ "items" in paramSchema &&
43
+ paramSchema.items?.type === "object");
44
+
45
+ const shouldRenderDescription = Boolean(
46
+ parameter.description ||
47
+ paramSchema.description ||
48
+ (paramSchema.type === "array" && paramSchema.items?.enum) ||
49
+ paramSchema.enum ||
50
+ paramSchema.example !== undefined ||
51
+ paramSchema.default !== undefined,
52
+ );
53
+
38
54
  return (
39
- <li className="p-4 bg-border/20 text-sm flex flex-col gap-1.5">
40
- <div className="flex items-center gap-2">
41
- <SelectOnClick asChild>
42
- <code>
43
- {group === "path" ? (
44
- <ColorizedParam
45
- name={parameter.name}
46
- backgroundOpacity="15%"
47
- className="px-2"
48
- slug={`${id}-${parameter.name}`}
55
+ <Item>
56
+ <ItemContent className="gap-y-2">
57
+ <div>
58
+ <ItemTitle className="inline me-2">
59
+ {isCollapsible ? (
60
+ <button
61
+ onClick={() => setIsOpen(!isOpen)}
62
+ type="button"
63
+ className="hover:underline"
64
+ >
65
+ <code>
66
+ {group === "path" ? (
67
+ <ColorizedParam
68
+ name={parameter.name}
69
+ backgroundOpacity="15%"
70
+ className="px-2"
71
+ slug={`${id}-${parameter.name}`}
72
+ />
73
+ ) : (
74
+ parameter.name
75
+ )}
76
+ </code>
77
+ </button>
78
+ ) : (
79
+ <code>
80
+ {group === "path" ? (
81
+ <ColorizedParam
82
+ name={parameter.name}
83
+ backgroundOpacity="15%"
84
+ className="px-2"
85
+ slug={`${id}-${parameter.name}`}
86
+ />
87
+ ) : (
88
+ parameter.name
89
+ )}
90
+ </code>
91
+ )}
92
+ </ItemTitle>
93
+ <ParamInfos
94
+ className="inline"
95
+ schema={paramSchema}
96
+ extraItems={[
97
+ parameter.required && (
98
+ <span className="text-primary">required</span>
99
+ ),
100
+ parameter.style && `style: ${parameter.style}`,
101
+ parameter.explode && `explode: ${parameter.explode}`,
102
+ ]}
103
+ />
104
+ </div>
105
+ {shouldRenderDescription && (
106
+ <div className="flex flex-col gap-1.5">
107
+ {parameter.description && (
108
+ <Markdown content={parameter.description} className="prose-sm" />
109
+ )}
110
+ {paramSchema.description && (
111
+ <Markdown
112
+ content={paramSchema.description}
113
+ className="prose-sm"
49
114
  />
115
+ )}
116
+ {paramSchema.type === "array" && paramSchema.items?.enum ? (
117
+ <EnumValues values={paramSchema.items.enum} />
50
118
  ) : (
51
- parameter.name
119
+ paramSchema.enum && <EnumValues values={paramSchema.enum} />
52
120
  )}
53
- </code>
54
- </SelectOnClick>
55
- <ParamInfos
56
- schema={paramSchema}
57
- extraItems={[
58
- parameter.required && (
59
- <span className="text-primary">required</span>
60
- ),
61
- parameter.style && `style: ${parameter.style}`,
62
- parameter.explode && `explode: ${parameter.explode}`,
63
- ]}
64
- />
65
- </div>
66
- {parameter.description && (
67
- <Markdown
68
- content={parameter.description}
69
- className="text-sm prose prose-p:my-1 prose-code:whitespace-pre-line"
70
- />
71
- )}
72
- {paramSchema.description && (
73
- <Markdown
74
- content={paramSchema.description}
75
- className="text-sm prose-p:my-1 prose-code:whitespace-pre-line"
76
- />
77
- )}
78
- {paramSchema.type === "array" && paramSchema.items.enum ? (
79
- <EnumValues values={paramSchema.items.enum} />
80
- ) : (
81
- paramSchema.enum && <EnumValues values={paramSchema.enum} />
121
+ <SchemaExampleAndDefault schema={paramSchema} />
122
+ </div>
123
+ )}
124
+ </ItemContent>
125
+
126
+ {isCollapsible && (
127
+ <ItemActions className="self-start">
128
+ <Button
129
+ variant="ghost"
130
+ size="icon"
131
+ className="rounded-full"
132
+ onClick={() => setIsOpen(!isOpen)}
133
+ aria-label="Toggle parameter"
134
+ >
135
+ {isOpen ? <MinusIcon size={16} /> : <PlusIcon size={16} />}
136
+ </Button>
137
+ </ItemActions>
82
138
  )}
83
- <SchemaExampleAndDefault schema={paramSchema} />
84
- {(paramSchema.type === "object" || isArrayType(paramSchema)) && (
139
+
140
+ {isCollapsible && (
85
141
  <Collapsible.Root
86
142
  defaultOpen={false}
87
- onOpenChange={setIsOpen}
88
143
  open={isOpen}
144
+ onOpenChange={setIsOpen}
145
+ className={cn("w-full", !isOpen && "contents")}
89
146
  >
90
- <Collapsible.Trigger asChild>
91
- <Button variant="expand" size="sm">
92
- {isOpen ? <MinusIcon size={12} /> : <PlusIcon size={12} />}
93
- {isOpen ? "Hide properties" : "Show properties"}
94
- </Button>
95
- </Collapsible.Trigger>
96
- <Collapsible.Content>
97
- <div className="mt-2">
147
+ <Collapsible.Content asChild>
148
+ <ItemContent>
98
149
  <SchemaView
99
150
  schema={
100
151
  "items" in paramSchema ? paramSchema.items : paramSchema
101
152
  }
102
153
  />
103
- </div>
154
+ </ItemContent>
104
155
  </Collapsible.Content>
105
156
  </Collapsible.Root>
106
157
  )}
107
- </li>
158
+ </Item>
108
159
  );
109
160
  };
@@ -1,3 +1,10 @@
1
+ import { ChevronsDownUpIcon, ChevronsUpDownIcon } from "lucide-react";
2
+ import { Button } from "zudoku/components";
3
+ import {
4
+ Collapsible,
5
+ CollapsibleContent,
6
+ CollapsibleTrigger,
7
+ } from "zudoku/ui/Collapsible.js";
1
8
  import type { MediaTypeObject } from "./graphql/graphql.js";
2
9
  import * as SidecarBox from "./SidecarBox.js";
3
10
  import { SidecarExamples } from "./SidecarExamples.js";
@@ -23,18 +30,34 @@ export const RequestBodySidecarBox = ({
23
30
  if (content.length === 0) return null;
24
31
 
25
32
  return (
26
- <SidecarBox.Root>
27
- <SidecarBox.Head className="text-xs flex justify-between items-center">
28
- <span className="font-mono">Request Body Example</span>
29
- </SidecarBox.Head>
30
- <SidecarExamples
31
- selectedContentIndex={selectedContentIndex}
32
- selectedExampleIndex={selectedExampleIndex}
33
- content={content}
34
- onExampleChange={onExampleChange}
35
- isOnScreen={isOnScreen}
36
- shouldLazyHighlight={shouldLazyHighlight}
37
- />
38
- </SidecarBox.Root>
33
+ <Collapsible className="group/collapsible" defaultOpen>
34
+ <SidecarBox.Root>
35
+ <SidecarBox.Head className="text-xs flex justify-between items-center">
36
+ <span className="flex items-center gap-1 font-medium">
37
+ <CollapsibleTrigger asChild>
38
+ <Button
39
+ variant="ghost"
40
+ className="size-fit px-1 py-1 -my-1"
41
+ aria-label="Toggle request body examples"
42
+ >
43
+ <ChevronsDownUpIcon className="size-[1em] group-data-[state=closed]/collapsible:hidden" />
44
+ <ChevronsUpDownIcon className="size-[1em] group-data-[state=open]/collapsible:hidden" />
45
+ </Button>
46
+ </CollapsibleTrigger>
47
+ Example Request Body
48
+ </span>
49
+ </SidecarBox.Head>
50
+ <CollapsibleContent>
51
+ <SidecarExamples
52
+ selectedContentIndex={selectedContentIndex}
53
+ selectedExampleIndex={selectedExampleIndex}
54
+ content={content}
55
+ onExampleChange={onExampleChange}
56
+ isOnScreen={isOnScreen}
57
+ shouldLazyHighlight={shouldLazyHighlight}
58
+ />
59
+ </CollapsibleContent>
60
+ </SidecarBox.Root>
61
+ </Collapsible>
39
62
  );
40
63
  };
@@ -1,6 +1,12 @@
1
- import * as Tabs from "@radix-ui/react-tabs";
1
+ import { ChevronsDownUpIcon, ChevronsUpDownIcon } from "lucide-react";
2
2
  import { useEffect, useState } from "react";
3
- import { cn } from "../../util/cn.js";
3
+ import { Button } from "zudoku/components";
4
+ import {
5
+ Collapsible,
6
+ CollapsibleContent,
7
+ CollapsibleTrigger,
8
+ } from "zudoku/ui/Collapsible.js";
9
+ import { NativeSelect, NativeSelectOption } from "zudoku/ui/NativeSelect.js";
4
10
  import type { ResponseItem } from "./graphql/graphql.js";
5
11
  import * as SidecarBox from "./SidecarBox.js";
6
12
  import { SidecarExamples } from "./SidecarExamples.js";
@@ -8,67 +14,84 @@ import { SidecarExamples } from "./SidecarExamples.js";
8
14
  export const ResponsesSidecarBox = ({
9
15
  responses,
10
16
  selectedResponse,
11
- onSelectResponse,
12
17
  isOnScreen,
13
18
  shouldLazyHighlight,
14
19
  }: {
15
20
  responses: ResponseItem[];
16
21
  selectedResponse?: string;
17
- onSelectResponse: (response: string) => void;
18
22
  isOnScreen: boolean;
19
23
  shouldLazyHighlight?: boolean;
20
24
  }) => {
25
+ const [internalSelectedResponse, setInternalSelectedResponse] = useState(
26
+ selectedResponse ?? responses[0]?.statusCode,
27
+ );
21
28
  const [selectedContentIndex, setSelectedContentIndex] = useState(0);
22
29
  const [selectedExampleIndex, setSelectedExampleIndex] = useState(0);
23
30
 
24
31
  useEffect(() => {
25
32
  if (!selectedResponse) return;
26
33
 
34
+ setInternalSelectedResponse(selectedResponse);
35
+ }, [selectedResponse]);
36
+
37
+ useEffect(() => {
38
+ if (!internalSelectedResponse) return;
39
+
27
40
  setSelectedContentIndex(0);
28
41
  setSelectedExampleIndex(0);
29
- }, [selectedResponse]);
42
+ }, [internalSelectedResponse]);
30
43
 
31
44
  return (
32
- <SidecarBox.Root>
33
- <Tabs.Root
34
- defaultValue={responses[0]?.statusCode}
35
- value={selectedResponse}
36
- onValueChange={(value) => onSelectResponse(value)}
37
- >
38
- <SidecarBox.Head className="text-xs flex flex-col gap-2 pb-0">
39
- <span className="font-mono">Example Responses</span>
40
- <Tabs.List className="flex gap-2">
41
- {responses.map((response) => (
42
- <Tabs.Trigger
43
- key={response.statusCode}
44
- value={response.statusCode}
45
- className={cn(
46
- "text-xs font-mono px-1.5 py-1 pb-px translate-y-px border-b-2 border-transparent rounded-t cursor-pointer",
47
- "data-[state=active]:text-primary data-[state=active]:dark:text-inherit data-[state=active]:border-primary",
48
- "hover:border-accent-foreground/25",
49
- )}
45
+ <Collapsible className="group/collapsible" defaultOpen>
46
+ <SidecarBox.Root>
47
+ <SidecarBox.Head className="text-xs flex justify-between items-center">
48
+ <div className="flex items-center gap-1 font-medium shrink-0">
49
+ <CollapsibleTrigger asChild>
50
+ <Button
51
+ variant="ghost"
52
+ className="size-fit px-1 py-1 -my-1"
53
+ aria-label="Toggle response examples"
50
54
  >
51
- {response.statusCode}
52
- </Tabs.Trigger>
53
- ))}
54
- </Tabs.List>
55
+ <ChevronsDownUpIcon className="size-[1em] group-data-[state=closed]/collapsible:hidden" />
56
+ <ChevronsUpDownIcon className="size-[1em] group-data-[state=open]/collapsible:hidden" />
57
+ </Button>
58
+ </CollapsibleTrigger>
59
+ Example Responses
60
+ </div>
61
+ <div className="group-data-[state=closed]/collapsible:hidden">
62
+ <NativeSelect
63
+ className="text-xs h-fit py-1 -my-1 bg-background"
64
+ value={internalSelectedResponse}
65
+ onChange={(e) => setInternalSelectedResponse(e.target.value)}
66
+ >
67
+ {responses.map((response) => (
68
+ <NativeSelectOption
69
+ key={response.statusCode}
70
+ value={response.statusCode}
71
+ >
72
+ {response.statusCode}
73
+ </NativeSelectOption>
74
+ ))}
75
+ </NativeSelect>
76
+ </div>
55
77
  </SidecarBox.Head>
56
- {responses.map((response) => (
57
- <Tabs.Content key={response.statusCode} value={response.statusCode}>
58
- <SidecarExamples
59
- selectedContentIndex={selectedContentIndex}
60
- selectedExampleIndex={selectedExampleIndex}
61
- onExampleChange={(selected) => {
62
- setSelectedContentIndex(selected.contentTypeIndex);
63
- setSelectedExampleIndex(selected.exampleIndex);
64
- }}
65
- content={response.content ?? []}
66
- isOnScreen={isOnScreen}
67
- shouldLazyHighlight={shouldLazyHighlight}
68
- />
69
- </Tabs.Content>
70
- ))}
71
- </Tabs.Root>
72
- </SidecarBox.Root>
78
+ <CollapsibleContent>
79
+ <SidecarExamples
80
+ selectedContentIndex={selectedContentIndex}
81
+ selectedExampleIndex={selectedExampleIndex}
82
+ onExampleChange={(selected) => {
83
+ setSelectedContentIndex(selected.contentTypeIndex);
84
+ setSelectedExampleIndex(selected.exampleIndex);
85
+ }}
86
+ content={
87
+ responses.find((r) => r.statusCode === internalSelectedResponse)
88
+ ?.content ?? []
89
+ }
90
+ isOnScreen={isOnScreen}
91
+ shouldLazyHighlight={shouldLazyHighlight}
92
+ />
93
+ </CollapsibleContent>
94
+ </SidecarBox.Root>
95
+ </Collapsible>
73
96
  );
74
97
  };
@@ -1,6 +1,8 @@
1
1
  import { useMemo, useState, useTransition } from "react";
2
2
  import { useSearchParams } from "react-router";
3
3
  import { useZudoku } from "zudoku/hooks";
4
+ import { Badge } from "zudoku/ui/Badge.js";
5
+ import { NativeSelect, NativeSelectOption } from "zudoku/ui/NativeSelect.js";
4
6
  import { SyntaxHighlight } from "zudoku/ui/SyntaxHighlight.js";
5
7
  import { useAuthState } from "../../authentication/state.js";
6
8
  import { PathRenderer } from "../../components/PathRenderer.js";
@@ -16,7 +18,6 @@ import { PlaygroundDialogWrapper } from "./PlaygroundDialogWrapper.js";
16
18
  import { RequestBodySidecarBox } from "./RequestBodySidecarBox.js";
17
19
  import { ResponsesSidecarBox } from "./ResponsesSidecarBox.js";
18
20
  import * as SidecarBox from "./SidecarBox.js";
19
- import { SimpleSelect } from "./SimpleSelect.js";
20
21
  import { createHttpSnippet, getConverted } from "./util/createHttpSnippet.js";
21
22
  import { generateSchemaExample } from "./util/generateSchemaExample.js";
22
23
  import { methodForColor } from "./util/methodToColor.js";
@@ -49,13 +50,11 @@ const EXAMPLE_LANGUAGES = [
49
50
  export const Sidecar = ({
50
51
  operation,
51
52
  selectedResponse,
52
- onSelectResponse,
53
53
  globalSelectedServer,
54
54
  shouldLazyHighlight,
55
55
  }: {
56
56
  operation: OperationsFragmentFragment;
57
57
  selectedResponse?: string;
58
- onSelectResponse: (response: string) => void;
59
58
  globalSelectedServer?: string;
60
59
  shouldLazyHighlight?: boolean;
61
60
  }) => {
@@ -68,6 +67,16 @@ export const Sidecar = ({
68
67
  const [searchParams, setSearchParams] = useSearchParams();
69
68
  const [, startTransition] = useTransition();
70
69
 
70
+ const supportedLanguages = options?.supportedLanguages ?? EXAMPLE_LANGUAGES;
71
+
72
+ const preferredLang =
73
+ searchParams.get("lang") ?? options?.examplesLanguage ?? "shell";
74
+
75
+ const selectedLang =
76
+ supportedLanguages.find((lang) => lang.value === preferredLang)?.value ??
77
+ supportedLanguages.at(0)?.value ??
78
+ "shell";
79
+
71
80
  const requestBodyContent = operation.requestBody?.content;
72
81
  const transformedRequestBodyContent =
73
82
  requestBodyContent && options?.transformExamples
@@ -95,9 +104,6 @@ export const Sidecar = ({
95
104
  selectedRequestExample.exampleIndex,
96
105
  );
97
106
 
98
- const selectedLang =
99
- searchParams.get("lang") ?? options?.examplesLanguage ?? "shell";
100
-
101
107
  const currentExampleCode = currentExample
102
108
  ? (currentExample?.value ?? currentExample)
103
109
  : selectedContent?.schema
@@ -111,6 +117,7 @@ export const Sidecar = ({
111
117
  <ColorizedParam
112
118
  name={name}
113
119
  backgroundOpacity="0"
120
+ className="py-px px-0.5"
114
121
  // same as in `ParameterListItem`
115
122
  slug={`${operation.slug}-${name}`}
116
123
  >
@@ -126,6 +133,17 @@ export const Sidecar = ({
126
133
  globalSelectedServer || operation.servers.at(0)?.url || "";
127
134
 
128
135
  const httpSnippetCode = useMemo<string | undefined>(() => {
136
+ const converted = options?.generateCodeSnippet?.({
137
+ selectedLang,
138
+ selectedServer,
139
+ context,
140
+ operation,
141
+ example: currentExampleCode,
142
+ auth,
143
+ });
144
+
145
+ if (converted) return converted;
146
+
129
147
  const snippet = createHttpSnippet({
130
148
  operation,
131
149
  selectedServer,
@@ -138,7 +156,15 @@ export const Sidecar = ({
138
156
  });
139
157
 
140
158
  return getConverted(snippet, selectedLang);
141
- }, [operation, selectedServer, selectedLang, currentExampleCode]);
159
+ }, [
160
+ currentExampleCode,
161
+ operation,
162
+ selectedServer,
163
+ selectedLang,
164
+ options,
165
+ auth,
166
+ context,
167
+ ]);
142
168
 
143
169
  const [ref, isOnScreen] = useOnScreen({ rootMargin: "200px 0px 200px 0px" });
144
170
 
@@ -150,30 +176,64 @@ export const Sidecar = ({
150
176
  operation.extensions["x-zudoku-playground-enabled"] === undefined &&
151
177
  !options?.disablePlayground));
152
178
 
179
+ const hasResponseExamples = operation.responses.some((response) =>
180
+ response.content?.some((content) => (content.examples?.length ?? 0) > 0),
181
+ );
182
+
153
183
  return (
154
184
  <aside
155
185
  ref={ref}
156
- className="flex flex-col overflow-hidden sticky top-(--scroll-padding) gap-4"
186
+ className="flex flex-col sticky top-(--scroll-padding) gap-4"
157
187
  data-pagefind-ignore="all"
158
188
  >
159
189
  <SidecarBox.Root>
160
- <SidecarBox.Head className="flex justify-between items-center flex-nowrap py-2.5 gap-2 text-xs">
161
- <span className="font-mono wrap-break-word leading-6">
162
- <span className={cn("font-semibold", methodTextColor)}>
163
- {operation.method.toUpperCase()}
190
+ <SidecarBox.Head className="py-1.5">
191
+ <div className="flex items-center flex-wrap gap-2 justify-between w-full">
192
+ <span className="font-mono wrap-break-word leading-6 space-x-1">
193
+ <Badge
194
+ variant="outline"
195
+ className={cn(
196
+ methodTextColor,
197
+ "px-1.5 rounded-md border-none bg-current/7 dark:bg-current/15",
198
+ )}
199
+ >
200
+ {operation.method.toUpperCase()}
201
+ </Badge>
202
+ {path}
164
203
  </span>
165
- &nbsp;
166
- {path}
167
- </span>
168
- {showPlayground && (
169
- <PlaygroundDialogWrapper
170
- servers={operation.servers.map((server) => server.url)}
171
- operation={operation}
172
- examples={requestBodyContent ?? undefined}
173
- />
174
- )}
204
+ <div className="flex items-center gap-1">
205
+ <NativeSelect
206
+ className="py-0.5 h-fit max-w-32 truncate bg-background"
207
+ value={selectedLang}
208
+ onChange={(e) => {
209
+ startTransition(() => {
210
+ setSearchParams((prev) => {
211
+ prev.set("lang", e.target.value);
212
+ return prev;
213
+ });
214
+ });
215
+ }}
216
+ >
217
+ {supportedLanguages.map((language) => (
218
+ <NativeSelectOption
219
+ key={language.value}
220
+ value={language.value}
221
+ >
222
+ {language.label}
223
+ </NativeSelectOption>
224
+ ))}
225
+ </NativeSelect>
226
+ {showPlayground && (
227
+ <PlaygroundDialogWrapper
228
+ servers={operation.servers.map((server) => server.url)}
229
+ operation={operation}
230
+ examples={requestBodyContent ?? undefined}
231
+ />
232
+ )}
233
+ </div>
234
+ </div>
175
235
  </SidecarBox.Head>
176
- <SidecarBox.Body className="p-0">
236
+ <SidecarBox.Body>
177
237
  {shouldLazyHighlight && !isOnScreen ? (
178
238
  <NonHighlightedCode code={httpSnippetCode ?? ""} />
179
239
  ) : (
@@ -186,22 +246,6 @@ export const Sidecar = ({
186
246
  />
187
247
  )}
188
248
  </SidecarBox.Body>
189
- <SidecarBox.Footer className="flex items-center text-xs gap-2 justify-end py-2.5">
190
- <span>Show example in</span>
191
- <SimpleSelect
192
- className="self-start max-w-[150px]"
193
- value={selectedLang}
194
- onChange={(e) => {
195
- startTransition(() => {
196
- setSearchParams((prev) => {
197
- prev.set("lang", e.target.value);
198
- return prev;
199
- });
200
- });
201
- }}
202
- options={EXAMPLE_LANGUAGES}
203
- />
204
- </SidecarBox.Footer>
205
249
  </SidecarBox.Root>
206
250
 
207
251
  {transformedRequestBodyContent && currentExample ? (
@@ -223,12 +267,11 @@ export const Sidecar = ({
223
267
  />
224
268
  ) : null}
225
269
 
226
- {operation.responses.length > 0 && (
270
+ {hasResponseExamples && (
227
271
  <ResponsesSidecarBox
228
272
  isOnScreen={isOnScreen}
229
273
  shouldLazyHighlight={shouldLazyHighlight}
230
274
  selectedResponse={selectedResponse}
231
- onSelectResponse={onSelectResponse}
232
275
  responses={operation.responses.map((response) => ({
233
276
  ...response,
234
277
  content:
@@ -7,7 +7,12 @@ type BaseComponentProps<T = unknown> = PropsWithChildren<
7
7
 
8
8
  export const Root = ({ children, className }: BaseComponentProps) => (
9
9
  <div
10
- className={cn("rounded-xl overflow-hidden border border-border", className)}
10
+ data-slot="sidecar-box-root"
11
+ className={cn(
12
+ "relative text-xs flex min-w-0 flex-col rounded-xl border bg-muted/50 bg-clip-padding",
13
+ "before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-xl)-1px)] before:shadow-[0_1px_2px_1px_--theme(--color-black/4%)] after:pointer-events-none after:absolute after:-inset-[5px] after:-z-1 after:rounded-[calc(var(--radius-xl)+4px)] after:border after:border-border/50 after:bg-clip-padding **:data-[slot=particle-wrapper]:w-full **:data-[slot=particle-wrapper]:max-w-64 lg:col-span-1 dark:after:bg-background/72",
14
+ className,
15
+ )}
11
16
  >
12
17
  {children}
13
18
  </div>
@@ -15,8 +20,9 @@ export const Root = ({ children, className }: BaseComponentProps) => (
15
20
 
16
21
  export const Head = ({ children, className }: BaseComponentProps) => (
17
22
  <div
23
+ data-slot="sidecar-box-head"
18
24
  className={cn(
19
- "border-b bg-muted dark:bg-transparent text-card-foreground p-3 py-2.5",
25
+ "flex items-center gap-3 rounded-b-xl p-2.5 data-[slot=head]:rounded-b-none",
20
26
  className,
21
27
  )}
22
28
  >
@@ -25,11 +31,27 @@ export const Head = ({ children, className }: BaseComponentProps) => (
25
31
  );
26
32
 
27
33
  export const Body = ({ children, className }: BaseComponentProps) => (
28
- <div className={cn("bg-card overflow-auto p-2", className)}>{children}</div>
34
+ <div
35
+ data-slot="sidecar-box-body"
36
+ className={cn(
37
+ "overflow-auto -m-px flex min-w-0 flex-1 flex-col overflow-x-auto rounded-t-xl border bg-background",
38
+ "rounded-b last:rounded-b-xl",
39
+ "before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-xl)-1px)] dark:before:shadow-[0_-1px_--theme(--color-white/8%)]",
40
+ className,
41
+ )}
42
+ >
43
+ {children}
44
+ </div>
29
45
  );
30
46
 
31
47
  export const Footer = ({ children, className }: BaseComponentProps) => (
32
- <div className={cn("border-t bg-muted dark:bg-transparent p-3", className)}>
48
+ <div
49
+ data-slot="sidecar-box-footer"
50
+ className={cn(
51
+ "p-2 rounded-b-xl data-[slot=sidecar-box-footer]:rounded-b-none",
52
+ className,
53
+ )}
54
+ >
33
55
  {children}
34
56
  </div>
35
57
  );