zudoku 0.45.1 → 0.46.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 (532) hide show
  1. package/dist/app/main.js +4 -23
  2. package/dist/app/main.js.map +1 -1
  3. package/dist/config/config.d.ts +2 -2
  4. package/dist/config/file-exists.d.ts +1 -0
  5. package/dist/config/file-exists.js +5 -0
  6. package/dist/config/file-exists.js.map +1 -0
  7. package/dist/config/loader.d.ts +19 -4
  8. package/dist/config/loader.js +94 -14
  9. package/dist/config/loader.js.map +1 -1
  10. package/dist/config/validators/validate.d.ts +3536 -743
  11. package/dist/config/validators/validate.js +396 -11
  12. package/dist/config/validators/validate.js.map +1 -1
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/lib/authentication/AuthenticationPlugin.d.ts +7 -2
  17. package/dist/lib/authentication/AuthenticationPlugin.js +13 -1
  18. package/dist/lib/authentication/AuthenticationPlugin.js.map +1 -1
  19. package/dist/lib/authentication/authentication.d.ts +2 -4
  20. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  21. package/dist/lib/authentication/providers/clerk.js +62 -43
  22. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  23. package/dist/lib/authentication/providers/openid.d.ts +7 -12
  24. package/dist/lib/authentication/providers/openid.js +11 -22
  25. package/dist/lib/authentication/providers/openid.js.map +1 -1
  26. package/dist/lib/authentication/providers/supabase.js +3 -5
  27. package/dist/lib/authentication/providers/supabase.js.map +1 -1
  28. package/dist/lib/components/Autocomplete.js +1 -1
  29. package/dist/lib/components/Banner.js +1 -1
  30. package/dist/lib/components/Banner.js.map +1 -1
  31. package/dist/lib/components/ErrorPage.js +1 -1
  32. package/dist/lib/components/Footer.js +3 -3
  33. package/dist/lib/components/Footer.js.map +1 -1
  34. package/dist/lib/components/Header.js +16 -8
  35. package/dist/lib/components/Header.js.map +1 -1
  36. package/dist/lib/components/Heading.js +6 -1
  37. package/dist/lib/components/Heading.js.map +1 -1
  38. package/dist/lib/components/InlineCode.js +1 -1
  39. package/dist/lib/components/InlineCode.js.map +1 -1
  40. package/dist/lib/components/Layout.js +2 -2
  41. package/dist/lib/components/Layout.js.map +1 -1
  42. package/dist/lib/components/Main.js +2 -2
  43. package/dist/lib/components/Main.js.map +1 -1
  44. package/dist/lib/components/Markdown.js +8 -3
  45. package/dist/lib/components/Markdown.js.map +1 -1
  46. package/dist/lib/components/MobileTopNavigation.js +3 -2
  47. package/dist/lib/components/MobileTopNavigation.js.map +1 -1
  48. package/dist/lib/components/NotFoundPage.js +1 -1
  49. package/dist/lib/components/Pagination.js +1 -1
  50. package/dist/lib/components/Pagination.js.map +1 -1
  51. package/dist/lib/components/Search.js +1 -1
  52. package/dist/lib/components/Search.js.map +1 -1
  53. package/dist/lib/components/Slot.d.ts +17 -0
  54. package/dist/lib/components/Slot.js +24 -0
  55. package/dist/lib/components/Slot.js.map +1 -0
  56. package/dist/lib/components/Slot.test.js +168 -0
  57. package/dist/lib/components/Slot.test.js.map +1 -0
  58. package/dist/lib/components/TopNavigation.d.ts +1 -4
  59. package/dist/lib/components/TopNavigation.js +3 -11
  60. package/dist/lib/components/TopNavigation.js.map +1 -1
  61. package/dist/lib/components/Zudoku.js +2 -2
  62. package/dist/lib/components/Zudoku.js.map +1 -1
  63. package/dist/lib/components/context/SlotProvider.d.ts +26 -0
  64. package/dist/lib/components/context/SlotProvider.js +83 -0
  65. package/dist/lib/components/context/SlotProvider.js.map +1 -0
  66. package/dist/lib/components/context/ZudokuContext.d.ts +1 -1
  67. package/dist/lib/components/context/ZudokuProvider.js +2 -1
  68. package/dist/lib/components/context/ZudokuProvider.js.map +1 -1
  69. package/dist/lib/components/index.d.ts +29 -23
  70. package/dist/lib/components/index.js +13 -7
  71. package/dist/lib/components/index.js.map +1 -1
  72. package/dist/lib/components/navigation/PoweredByZudoku.js +1 -1
  73. package/dist/lib/components/navigation/Sidebar.js +3 -3
  74. package/dist/lib/components/navigation/Sidebar.js.map +1 -1
  75. package/dist/lib/components/navigation/SidebarBadge.js +1 -1
  76. package/dist/lib/components/navigation/SidebarBadge.js.map +1 -1
  77. package/dist/lib/components/navigation/SidebarCategory.js +3 -3
  78. package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
  79. package/dist/lib/components/navigation/SidebarItem.d.ts +0 -5
  80. package/dist/lib/components/navigation/SidebarItem.js +19 -23
  81. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  82. package/dist/lib/components/navigation/SidebarWrapper.js +1 -1
  83. package/dist/lib/components/navigation/Toc.js +1 -1
  84. package/dist/lib/components/navigation/Toc.js.map +1 -1
  85. package/dist/lib/components/navigation/utils.d.ts +8 -0
  86. package/dist/lib/components/navigation/utils.js +34 -6
  87. package/dist/lib/components/navigation/utils.js.map +1 -1
  88. package/dist/lib/core/ZudokuContext.d.ts +12 -8
  89. package/dist/lib/core/ZudokuContext.js +6 -5
  90. package/dist/lib/core/ZudokuContext.js.map +1 -1
  91. package/dist/lib/core/plugins.d.ts +5 -2
  92. package/dist/lib/core/plugins.js +1 -0
  93. package/dist/lib/core/plugins.js.map +1 -1
  94. package/dist/lib/errors/ErrorAlert.js +1 -1
  95. package/dist/lib/hooks/index.d.ts +19 -0
  96. package/dist/lib/hooks/index.js +11 -0
  97. package/dist/lib/hooks/index.js.map +1 -1
  98. package/dist/lib/plugins/api-catalog/Catalog.js +1 -1
  99. package/dist/lib/plugins/api-keys/CreateApiKey.d.ts +3 -2
  100. package/dist/lib/plugins/api-keys/CreateApiKey.js +8 -4
  101. package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -1
  102. package/dist/lib/plugins/api-keys/SettingsApiKeys.d.ts +1 -1
  103. package/dist/lib/plugins/api-keys/SettingsApiKeys.js +54 -23
  104. package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
  105. package/dist/lib/plugins/api-keys/index.d.ts +18 -9
  106. package/dist/lib/plugins/api-keys/index.js +49 -34
  107. package/dist/lib/plugins/api-keys/index.js.map +1 -1
  108. package/dist/lib/plugins/custom-pages/index.d.ts +1 -1
  109. package/dist/lib/plugins/markdown/MdxPage.js +1 -1
  110. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  111. package/dist/lib/plugins/markdown/index.d.ts +1 -1
  112. package/dist/lib/plugins/markdown/resolver.d.ts +1 -1
  113. package/dist/lib/plugins/markdown/resolver.js.map +1 -1
  114. package/dist/lib/plugins/openapi/CollapsibleCode.js +1 -1
  115. package/dist/lib/plugins/openapi/ColorizedParam.js +1 -1
  116. package/dist/lib/plugins/openapi/ColorizedParam.js.map +1 -1
  117. package/dist/lib/plugins/openapi/OperationList.js +1 -1
  118. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  119. package/dist/lib/plugins/openapi/OperationListItem.js +2 -3
  120. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  121. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js +5 -1
  122. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -1
  123. package/dist/lib/plugins/openapi/ResponsesSidecarBox.d.ts +2 -4
  124. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +1 -4
  125. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
  126. package/dist/lib/plugins/openapi/SchemaList.js +6 -5
  127. package/dist/lib/plugins/openapi/SchemaList.js.map +1 -1
  128. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  129. package/dist/lib/plugins/openapi/SidecarExamples.js +8 -0
  130. package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
  131. package/dist/lib/plugins/openapi/components/EnumValues.js +1 -1
  132. package/dist/lib/plugins/openapi/components/EnumValues.js.map +1 -1
  133. package/dist/lib/plugins/openapi/components/ResponseContent.d.ts +12 -0
  134. package/dist/lib/plugins/openapi/components/ResponseContent.js +21 -0
  135. package/dist/lib/plugins/openapi/components/ResponseContent.js.map +1 -0
  136. package/dist/lib/plugins/openapi/playground/Playground.js +2 -0
  137. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  138. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +1 -1
  139. package/dist/lib/plugins/openapi/playground/SubmitButton.js +7 -10
  140. package/dist/lib/plugins/openapi/playground/SubmitButton.js.map +1 -1
  141. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js +2 -2
  142. package/dist/lib/plugins/openapi/schema/SchemaExampleAndDefault.js.map +1 -1
  143. package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +2 -1
  144. package/dist/lib/plugins/openapi/schema/SchemaView.js +3 -3
  145. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  146. package/dist/lib/plugins/redirect/index.d.ts +1 -1
  147. package/dist/lib/ui/Badge.d.ts +2 -2
  148. package/dist/lib/ui/Badge.js +1 -1
  149. package/dist/lib/ui/Badge.js.map +1 -1
  150. package/dist/lib/ui/Button.d.ts +2 -2
  151. package/dist/lib/ui/Button.js +8 -6
  152. package/dist/lib/ui/Button.js.map +1 -1
  153. package/dist/lib/ui/Callout.js +1 -1
  154. package/dist/lib/ui/Callout.js.map +1 -1
  155. package/dist/lib/ui/Card.js +1 -1
  156. package/dist/lib/ui/Checkbox.js +1 -1
  157. package/dist/lib/ui/Checkbox.js.map +1 -1
  158. package/dist/lib/ui/Command.d.ts +2 -2
  159. package/dist/lib/ui/Command.js +3 -3
  160. package/dist/lib/ui/Command.js.map +1 -1
  161. package/dist/lib/ui/Dialog.js +1 -1
  162. package/dist/lib/ui/Dialog.js.map +1 -1
  163. package/dist/lib/ui/DropdownMenu.js +4 -4
  164. package/dist/lib/ui/DropdownMenu.js.map +1 -1
  165. package/dist/lib/ui/HoverCard.js +1 -1
  166. package/dist/lib/ui/HoverCard.js.map +1 -1
  167. package/dist/lib/ui/Input.js +1 -1
  168. package/dist/lib/ui/Input.js.map +1 -1
  169. package/dist/lib/ui/Popover.js +1 -1
  170. package/dist/lib/ui/Popover.js.map +1 -1
  171. package/dist/lib/ui/RadioGroup.js +1 -1
  172. package/dist/lib/ui/RadioGroup.js.map +1 -1
  173. package/dist/lib/ui/Select.js +2 -2
  174. package/dist/lib/ui/Select.js.map +1 -1
  175. package/dist/lib/ui/Slider.js +1 -1
  176. package/dist/lib/ui/Slider.js.map +1 -1
  177. package/dist/lib/ui/Switch.js +1 -1
  178. package/dist/lib/ui/Switch.js.map +1 -1
  179. package/dist/lib/ui/Tabs.js +2 -2
  180. package/dist/lib/ui/Tabs.js.map +1 -1
  181. package/dist/lib/ui/Textarea.js +1 -1
  182. package/dist/lib/ui/Textarea.js.map +1 -1
  183. package/dist/lib/ui/Toggle.js +1 -1
  184. package/dist/lib/ui/Toggle.js.map +1 -1
  185. package/dist/lib/ui/Tooltip.d.ts +2 -1
  186. package/dist/lib/ui/Tooltip.js +2 -1
  187. package/dist/lib/ui/Tooltip.js.map +1 -1
  188. package/dist/lib/util/useExposedProps.d.ts +8 -1
  189. package/dist/lib/util/useExposedProps.js.map +1 -1
  190. package/dist/vite/api/SchemaManager.js +16 -1
  191. package/dist/vite/api/SchemaManager.js.map +1 -1
  192. package/dist/vite/build.js +44 -6
  193. package/dist/vite/build.js.map +1 -1
  194. package/dist/vite/config.d.ts +2 -9
  195. package/dist/vite/config.js +6 -95
  196. package/dist/vite/config.js.map +1 -1
  197. package/dist/vite/config.test.js +1 -1
  198. package/dist/vite/config.test.js.map +1 -1
  199. package/dist/vite/css/plugin.d.ts +1 -2
  200. package/dist/vite/css/plugin.js +3 -2
  201. package/dist/vite/css/plugin.js.map +1 -1
  202. package/dist/vite/dev-server.d.ts +0 -1
  203. package/dist/vite/dev-server.js +10 -12
  204. package/dist/vite/dev-server.js.map +1 -1
  205. package/dist/vite/html.d.ts +2 -2
  206. package/dist/vite/html.js +5 -2
  207. package/dist/vite/html.js.map +1 -1
  208. package/dist/vite/plugin-api-keys.d.ts +1 -2
  209. package/dist/vite/plugin-api-keys.js +9 -3
  210. package/dist/vite/plugin-api-keys.js.map +1 -1
  211. package/dist/vite/plugin-api.d.ts +1 -2
  212. package/dist/vite/plugin-api.js +5 -4
  213. package/dist/vite/plugin-api.js.map +1 -1
  214. package/dist/vite/plugin-auth.d.ts +1 -2
  215. package/dist/vite/plugin-auth.js +3 -2
  216. package/dist/vite/plugin-auth.js.map +1 -1
  217. package/dist/vite/plugin-component.d.ts +1 -2
  218. package/dist/vite/plugin-component.js +3 -2
  219. package/dist/vite/plugin-component.js.map +1 -1
  220. package/dist/vite/plugin-config-reload.d.ts +1 -2
  221. package/dist/vite/plugin-config-reload.js +21 -22
  222. package/dist/vite/plugin-config-reload.js.map +1 -1
  223. package/dist/vite/plugin-config.d.ts +1 -2
  224. package/dist/vite/plugin-config.js +4 -3
  225. package/dist/vite/plugin-config.js.map +1 -1
  226. package/dist/vite/plugin-configure-tailwind.d.ts +2 -0
  227. package/dist/vite/plugin-configure-tailwind.js +38 -0
  228. package/dist/vite/plugin-configure-tailwind.js.map +1 -0
  229. package/dist/vite/plugin-custom-pages.d.ts +1 -2
  230. package/dist/vite/plugin-custom-pages.js +3 -2
  231. package/dist/vite/plugin-custom-pages.js.map +1 -1
  232. package/dist/vite/plugin-docs.d.ts +1 -2
  233. package/dist/vite/plugin-docs.js +4 -3
  234. package/dist/vite/plugin-docs.js.map +1 -1
  235. package/dist/vite/plugin-frontmatter.d.ts +1 -2
  236. package/dist/vite/plugin-frontmatter.js +3 -2
  237. package/dist/vite/plugin-frontmatter.js.map +1 -1
  238. package/dist/vite/plugin-mdx.d.ts +1 -2
  239. package/dist/vite/plugin-mdx.js +3 -2
  240. package/dist/vite/plugin-mdx.js.map +1 -1
  241. package/dist/vite/plugin-redirect.d.ts +1 -2
  242. package/dist/vite/plugin-redirect.js +3 -2
  243. package/dist/vite/plugin-redirect.js.map +1 -1
  244. package/dist/vite/plugin-search.d.ts +1 -2
  245. package/dist/vite/plugin-search.js +3 -2
  246. package/dist/vite/plugin-search.js.map +1 -1
  247. package/dist/vite/plugin-shiki-register.d.ts +1 -2
  248. package/dist/vite/plugin-shiki-register.js +2 -1
  249. package/dist/vite/plugin-shiki-register.js.map +1 -1
  250. package/dist/vite/plugin-sidebar.d.ts +1 -2
  251. package/dist/vite/plugin-sidebar.js +3 -2
  252. package/dist/vite/plugin-sidebar.js.map +1 -1
  253. package/dist/vite/plugin-theme-css.d.ts +1 -2
  254. package/dist/vite/plugin-theme-css.js +20 -60
  255. package/dist/vite/plugin-theme-css.js.map +1 -1
  256. package/dist/vite/plugin.d.ts +1 -2
  257. package/dist/vite/plugin.js +22 -21
  258. package/dist/vite/plugin.js.map +1 -1
  259. package/dist/vite/sitemap.d.ts +1 -1
  260. package/dist/zuplo/with-zuplo.d.ts +2 -2
  261. package/dist/zuplo/with-zuplo.js.map +1 -1
  262. package/lib/Button-BE9IVkWV.js +51 -0
  263. package/lib/Button-BE9IVkWV.js.map +1 -0
  264. package/lib/{Callout-XadUe37J.js → Callout-BkgOUkoZ.js} +9 -8
  265. package/lib/Callout-BkgOUkoZ.js.map +1 -0
  266. package/lib/{Card-BlCYNw5W.js → Card-DPhGbYUM.js} +3 -3
  267. package/lib/{Card-BlCYNw5W.js.map → Card-DPhGbYUM.js.map} +1 -1
  268. package/lib/{CategoryHeading-DZi-Szor.js → CategoryHeading-Cu2RwgjC.js} +2 -2
  269. package/lib/{CategoryHeading-DZi-Szor.js.map → CategoryHeading-Cu2RwgjC.js.map} +1 -1
  270. package/lib/{Dialog-CNf2oWXG.js → Dialog-Du6WMcIA.js} +8 -7
  271. package/lib/Dialog-Du6WMcIA.js.map +1 -0
  272. package/lib/{Drawer-BPBxzel2.js → Drawer-BzkOKwgC.js} +2 -2
  273. package/lib/{Drawer-BPBxzel2.js.map → Drawer-BzkOKwgC.js.map} +1 -1
  274. package/lib/Markdown-BRAyzyUJ.js +15348 -0
  275. package/lib/Markdown-BRAyzyUJ.js.map +1 -0
  276. package/lib/{MdxPage-tTTaDsLc.js → MdxPage-B3v1BSKr.js} +11 -11
  277. package/lib/MdxPage-B3v1BSKr.js.map +1 -0
  278. package/lib/{OasProvider-DalHQixM.js → OasProvider-5jrFuhVk.js} +3 -3
  279. package/lib/{OasProvider-DalHQixM.js.map → OasProvider-5jrFuhVk.js.map} +1 -1
  280. package/lib/{OperationList-BB09ENaq.js → OperationList-BmoMLQPO.js} +1039 -1005
  281. package/lib/OperationList-BmoMLQPO.js.map +1 -0
  282. package/lib/Pagination-Cr0fWZS3.js +36 -0
  283. package/lib/Pagination-Cr0fWZS3.js.map +1 -0
  284. package/lib/RouteGuard-PrSVLbSr.js +55 -0
  285. package/lib/RouteGuard-PrSVLbSr.js.map +1 -0
  286. package/lib/{SchemaList-BH9bgMRw.js → SchemaList-B4riYLoP.js} +61 -47
  287. package/lib/SchemaList-B4riYLoP.js.map +1 -0
  288. package/lib/{SchemaView-BsB7EFRl.js → SchemaView-CPZ6RgsF.js} +100 -95
  289. package/lib/SchemaView-CPZ6RgsF.js.map +1 -0
  290. package/lib/{AuthenticationPlugin-BTJ37DKg.js → SignUp-CWaiH0tY.js} +23 -50
  291. package/lib/SignUp-CWaiH0tY.js.map +1 -0
  292. package/lib/Slot-Bo6K4tnb.js +160 -0
  293. package/lib/Slot-Bo6K4tnb.js.map +1 -0
  294. package/lib/{SyntaxHighlight-UxOF1xNb.js → SyntaxHighlight-DedRjJNr.js} +233 -212
  295. package/lib/{SyntaxHighlight-UxOF1xNb.js.map → SyntaxHighlight-DedRjJNr.js.map} +1 -1
  296. package/lib/{Toc-Ax54Pw8S.js → Toc-lL3fzNkl.js} +5 -5
  297. package/lib/Toc-lL3fzNkl.js.map +1 -0
  298. package/lib/{circular-CZaZtOBs.js → circular-oB4auIIg.js} +2 -2
  299. package/lib/{circular-CZaZtOBs.js.map → circular-oB4auIIg.js.map} +1 -1
  300. package/lib/clsx-OuTLNxxd.js +17 -0
  301. package/lib/clsx-OuTLNxxd.js.map +1 -0
  302. package/lib/{cn-CwJPJKOE.js → cn-wvCW-ho6.js} +1015 -562
  303. package/lib/cn-wvCW-ho6.js.map +1 -0
  304. package/lib/{createServer-DmqFeMgf.js → createServer-DCB82j2t.js} +81 -81
  305. package/lib/{createServer-DmqFeMgf.js.map → createServer-DCB82j2t.js.map} +1 -1
  306. package/lib/{hook-BwOB_iZo.js → hook-DawSLaZr.js} +323 -300
  307. package/lib/hook-DawSLaZr.js.map +1 -0
  308. package/lib/{index-sS7O9W-R.js → index-BXYvD5-7.js} +868 -758
  309. package/lib/index-BXYvD5-7.js.map +1 -0
  310. package/lib/{index-Z13x6tPX.js → index-DI5SPFK9.js} +2 -2
  311. package/lib/{index-Z13x6tPX.js.map → index-DI5SPFK9.js.map} +1 -1
  312. package/lib/index-QzXzw_ra.js +24 -0
  313. package/lib/index-QzXzw_ra.js.map +1 -0
  314. package/lib/{RouteGuard-lkdEJoDV.js → index.esm-BFcSKCe-.js} +232 -281
  315. package/lib/index.esm-BFcSKCe-.js.map +1 -0
  316. package/lib/{index.esm-D2ZUREQN.js → index.esm-DSfX_eMP.js} +3 -3
  317. package/lib/{index.esm-D2ZUREQN.js.map → index.esm-DSfX_eMP.js.map} +1 -1
  318. package/lib/joinPath-B7kNnUX4.js +8 -0
  319. package/lib/joinPath-B7kNnUX4.js.map +1 -0
  320. package/lib/{mutation-CL2MCRQL.js → mutation-oxMvODNQ.js} +2 -2
  321. package/lib/{mutation-CL2MCRQL.js.map → mutation-oxMvODNQ.js.map} +1 -1
  322. package/lib/ui/Accordion.js +1 -1
  323. package/lib/ui/ActionButton.js +2 -2
  324. package/lib/ui/Alert.js +2 -2
  325. package/lib/ui/AlertDialog.js +1 -1
  326. package/lib/ui/Badge.js +3 -3
  327. package/lib/ui/Badge.js.map +1 -1
  328. package/lib/ui/Breadcrumb.js +1 -1
  329. package/lib/ui/Button.js +20 -18
  330. package/lib/ui/Button.js.map +1 -1
  331. package/lib/ui/Callout.js +6 -5
  332. package/lib/ui/Callout.js.map +1 -1
  333. package/lib/ui/Card.js +8 -8
  334. package/lib/ui/Card.js.map +1 -1
  335. package/lib/ui/Carousel.js +1 -1
  336. package/lib/ui/Checkbox.js +7 -7
  337. package/lib/ui/Checkbox.js.map +1 -1
  338. package/lib/ui/CodeBlock.js +1 -1
  339. package/lib/ui/Command.js +43 -43
  340. package/lib/ui/Command.js.map +1 -1
  341. package/lib/ui/Dialog.js +2 -2
  342. package/lib/ui/Dialog.js.map +1 -1
  343. package/lib/ui/Drawer.js +2 -2
  344. package/lib/ui/DropdownMenu.js +34 -34
  345. package/lib/ui/DropdownMenu.js.map +1 -1
  346. package/lib/ui/Form.js +2 -2
  347. package/lib/ui/HoverCard.js +5 -5
  348. package/lib/ui/HoverCard.js.map +1 -1
  349. package/lib/ui/Input.js +2 -2
  350. package/lib/ui/Input.js.map +1 -1
  351. package/lib/ui/Label.js +2 -2
  352. package/lib/ui/Pagination.js +1 -1
  353. package/lib/ui/Popover.js +2 -2
  354. package/lib/ui/Popover.js.map +1 -1
  355. package/lib/ui/Progress.js +1 -1
  356. package/lib/ui/RadioGroup.js +10 -10
  357. package/lib/ui/RadioGroup.js.map +1 -1
  358. package/lib/ui/ScrollArea.js +1 -1
  359. package/lib/ui/Select.js +31 -31
  360. package/lib/ui/Select.js.map +1 -1
  361. package/lib/ui/Skeleton.js +1 -1
  362. package/lib/ui/Slider.js +5 -5
  363. package/lib/ui/Slider.js.map +1 -1
  364. package/lib/ui/Switch.js +5 -5
  365. package/lib/ui/Switch.js.map +1 -1
  366. package/lib/ui/SyntaxHighlight.js +2 -2
  367. package/lib/ui/Tabs.js +16 -16
  368. package/lib/ui/Tabs.js.map +1 -1
  369. package/lib/ui/Textarea.js +5 -5
  370. package/lib/ui/Textarea.js.map +1 -1
  371. package/lib/ui/Toggle.js +7 -7
  372. package/lib/ui/Toggle.js.map +1 -1
  373. package/lib/ui/ToggleGroup.js +1 -1
  374. package/lib/ui/Tooltip.js +15 -8
  375. package/lib/ui/Tooltip.js.map +1 -1
  376. package/lib/ui/util.js +1 -1
  377. package/lib/useExposedProps-DG8J6ewJ.js.map +1 -1
  378. package/lib/useMutation-C_j3dA_L.js +97 -0
  379. package/lib/useMutation-C_j3dA_L.js.map +1 -0
  380. package/lib/zudoku.auth-auth0.js +1 -1
  381. package/lib/zudoku.auth-auth0.js.map +1 -1
  382. package/lib/zudoku.auth-clerk.js +99 -82
  383. package/lib/zudoku.auth-clerk.js.map +1 -1
  384. package/lib/zudoku.auth-openid.js +246 -216
  385. package/lib/zudoku.auth-openid.js.map +1 -1
  386. package/lib/zudoku.components.js +4957 -33
  387. package/lib/zudoku.components.js.map +1 -1
  388. package/lib/zudoku.hooks.js +21 -12
  389. package/lib/zudoku.hooks.js.map +1 -1
  390. package/lib/zudoku.plugin-api-catalog.js +8 -8
  391. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  392. package/lib/zudoku.plugin-api-keys.js +5022 -214
  393. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  394. package/lib/zudoku.plugin-custom-pages.js +2 -2
  395. package/lib/zudoku.plugin-custom-pages.js.map +1 -1
  396. package/lib/zudoku.plugin-markdown.js +1 -1
  397. package/lib/zudoku.plugin-markdown.js.map +1 -1
  398. package/lib/zudoku.plugin-openapi.js +3 -3
  399. package/lib/zudoku.plugin-redirect.js.map +1 -1
  400. package/lib/zudoku.plugin-search-pagefind.js +5 -5
  401. package/lib/zudoku.plugins.js +7 -6
  402. package/lib/zudoku.plugins.js.map +1 -1
  403. package/package.json +15 -15
  404. package/src/app/defaultTheme.css +54 -0
  405. package/src/app/font.geist.css +73 -0
  406. package/src/app/main.css +113 -156
  407. package/src/app/main.tsx +4 -28
  408. package/src/lib/authentication/AuthenticationPlugin.tsx +18 -4
  409. package/src/lib/authentication/authentication.ts +2 -5
  410. package/src/lib/authentication/providers/auth0.tsx +8 -2
  411. package/src/lib/authentication/providers/clerk.tsx +72 -48
  412. package/src/lib/authentication/providers/openid.tsx +19 -26
  413. package/src/lib/authentication/providers/supabase.tsx +7 -7
  414. package/src/lib/components/Autocomplete.tsx +1 -1
  415. package/src/lib/components/Banner.tsx +1 -1
  416. package/src/lib/components/ErrorPage.tsx +1 -1
  417. package/src/lib/components/Footer.tsx +4 -4
  418. package/src/lib/components/Header.tsx +29 -29
  419. package/src/lib/components/Heading.tsx +9 -5
  420. package/src/lib/components/InlineCode.tsx +1 -1
  421. package/src/lib/components/Layout.tsx +3 -3
  422. package/src/lib/components/Main.tsx +4 -4
  423. package/src/lib/components/Markdown.tsx +14 -4
  424. package/src/lib/components/MobileTopNavigation.tsx +3 -2
  425. package/src/lib/components/NotFoundPage.tsx +1 -1
  426. package/src/lib/components/Pagination.tsx +3 -9
  427. package/src/lib/components/Search.tsx +1 -1
  428. package/src/lib/components/Slot.test.tsx +465 -0
  429. package/src/lib/components/Slot.tsx +64 -0
  430. package/src/lib/components/TopNavigation.tsx +5 -17
  431. package/src/lib/components/Zudoku.tsx +9 -9
  432. package/src/lib/components/context/SlotProvider.tsx +149 -0
  433. package/src/lib/components/context/ZudokuProvider.tsx +2 -1
  434. package/src/lib/components/index.ts +14 -10
  435. package/src/lib/components/navigation/PoweredByZudoku.tsx +1 -1
  436. package/src/lib/components/navigation/Sidebar.tsx +3 -3
  437. package/src/lib/components/navigation/SidebarBadge.tsx +1 -1
  438. package/src/lib/components/navigation/SidebarCategory.tsx +3 -3
  439. package/src/lib/components/navigation/SidebarItem.tsx +57 -30
  440. package/src/lib/components/navigation/SidebarWrapper.tsx +2 -2
  441. package/src/lib/components/navigation/Toc.tsx +2 -2
  442. package/src/lib/components/navigation/utils.ts +42 -6
  443. package/src/lib/core/ZudokuContext.ts +24 -12
  444. package/src/lib/core/plugins.ts +10 -2
  445. package/src/lib/errors/ErrorAlert.tsx +1 -1
  446. package/src/lib/hooks/index.ts +11 -0
  447. package/src/lib/plugins/api-catalog/Catalog.tsx +1 -1
  448. package/src/lib/plugins/api-keys/CreateApiKey.tsx +54 -42
  449. package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +292 -112
  450. package/src/lib/plugins/api-keys/index.tsx +101 -55
  451. package/src/lib/plugins/custom-pages/index.tsx +1 -1
  452. package/src/lib/plugins/markdown/MdxPage.tsx +2 -2
  453. package/src/lib/plugins/markdown/index.tsx +2 -2
  454. package/src/lib/plugins/markdown/resolver.ts +4 -2
  455. package/src/lib/plugins/openapi/CollapsibleCode.tsx +1 -1
  456. package/src/lib/plugins/openapi/ColorizedParam.tsx +2 -2
  457. package/src/lib/plugins/openapi/OperationList.tsx +2 -2
  458. package/src/lib/plugins/openapi/OperationListItem.tsx +6 -34
  459. package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +7 -1
  460. package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +5 -16
  461. package/src/lib/plugins/openapi/SchemaList.tsx +20 -8
  462. package/src/lib/plugins/openapi/Sidecar.tsx +1 -1
  463. package/src/lib/plugins/openapi/SidecarExamples.tsx +6 -0
  464. package/src/lib/plugins/openapi/components/EnumValues.tsx +1 -1
  465. package/src/lib/plugins/openapi/components/ResponseContent.tsx +104 -0
  466. package/src/lib/plugins/openapi/playground/Playground.tsx +7 -1
  467. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +1 -1
  468. package/src/lib/plugins/openapi/playground/SubmitButton.tsx +24 -29
  469. package/src/lib/plugins/openapi/schema/SchemaExampleAndDefault.tsx +2 -2
  470. package/src/lib/plugins/openapi/schema/SchemaView.tsx +7 -3
  471. package/src/lib/plugins/redirect/index.tsx +1 -1
  472. package/src/lib/ui/Badge.tsx +2 -2
  473. package/src/lib/ui/Button.tsx +9 -6
  474. package/src/lib/ui/Callout.tsx +1 -0
  475. package/src/lib/ui/Card.tsx +1 -1
  476. package/src/lib/ui/Checkbox.tsx +1 -1
  477. package/src/lib/ui/Command.tsx +5 -5
  478. package/src/lib/ui/Dialog.tsx +1 -1
  479. package/src/lib/ui/DropdownMenu.tsx +4 -4
  480. package/src/lib/ui/HoverCard.tsx +1 -1
  481. package/src/lib/ui/Input.tsx +1 -1
  482. package/src/lib/ui/Popover.tsx +1 -1
  483. package/src/lib/ui/RadioGroup.tsx +1 -1
  484. package/src/lib/ui/Select.tsx +3 -3
  485. package/src/lib/ui/Slider.tsx +1 -1
  486. package/src/lib/ui/Switch.tsx +1 -1
  487. package/src/lib/ui/Tabs.tsx +2 -2
  488. package/src/lib/ui/Textarea.tsx +1 -1
  489. package/src/lib/ui/Toggle.tsx +1 -1
  490. package/src/lib/ui/Tooltip.tsx +16 -1
  491. package/src/lib/util/useExposedProps.tsx +12 -1
  492. package/dist/app/tailwind.d.ts +0 -4
  493. package/dist/app/tailwind.js +0 -97
  494. package/dist/app/tailwind.js.map +0 -1
  495. package/dist/config/common.d.ts +0 -10
  496. package/dist/config/common.js +0 -2
  497. package/dist/config/common.js.map +0 -1
  498. package/dist/config/validators/common.d.ts +0 -8001
  499. package/dist/config/validators/common.js +0 -414
  500. package/dist/config/validators/common.js.map +0 -1
  501. package/dist/lib/components/SlotletProvider.d.ts +0 -17
  502. package/dist/lib/components/SlotletProvider.js +0 -18
  503. package/dist/lib/components/SlotletProvider.js.map +0 -1
  504. package/dist/vite/plugin-docs.test.js +0 -22
  505. package/dist/vite/plugin-docs.test.js.map +0 -1
  506. package/lib/AuthenticationPlugin-BTJ37DKg.js.map +0 -1
  507. package/lib/Button-Bdk_Ij3U.js +0 -49
  508. package/lib/Button-Bdk_Ij3U.js.map +0 -1
  509. package/lib/Callout-XadUe37J.js.map +0 -1
  510. package/lib/Dialog-CNf2oWXG.js.map +0 -1
  511. package/lib/Markdown-D96AphCL.js +0 -7691
  512. package/lib/Markdown-D96AphCL.js.map +0 -1
  513. package/lib/MdxPage-tTTaDsLc.js.map +0 -1
  514. package/lib/OperationList-BB09ENaq.js.map +0 -1
  515. package/lib/Pagination-CtmnJOJi.js +0 -48
  516. package/lib/Pagination-CtmnJOJi.js.map +0 -1
  517. package/lib/RouteGuard-lkdEJoDV.js.map +0 -1
  518. package/lib/SchemaList-BH9bgMRw.js.map +0 -1
  519. package/lib/SchemaView-BsB7EFRl.js.map +0 -1
  520. package/lib/Select-HTio1oSE.js +0 -211
  521. package/lib/Select-HTio1oSE.js.map +0 -1
  522. package/lib/SlotletProvider-CTgIBRWg.js +0 -257
  523. package/lib/SlotletProvider-CTgIBRWg.js.map +0 -1
  524. package/lib/Toc-Ax54Pw8S.js.map +0 -1
  525. package/lib/cn-CwJPJKOE.js.map +0 -1
  526. package/lib/hook-BwOB_iZo.js.map +0 -1
  527. package/lib/index-BnT4-Efz.js +0 -4975
  528. package/lib/index-BnT4-Efz.js.map +0 -1
  529. package/lib/index-sS7O9W-R.js.map +0 -1
  530. package/src/app/tailwind.ts +0 -103
  531. package/src/lib/components/SlotletProvider.tsx +0 -55
  532. /package/dist/{vite/plugin-docs.test.d.ts → lib/components/Slot.test.d.ts} +0 -0
@@ -0,0 +1,465 @@
1
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
2
+ import {
3
+ act,
4
+ screen,
5
+ render as testRender,
6
+ type RenderResult,
7
+ } from "@testing-library/react";
8
+ import type { PropsWithChildren, ReactNode } from "react";
9
+ import { useEffect, useState } from "react";
10
+ import { MemoryRouter } from "react-router";
11
+ import { describe, expect, it } from "vitest";
12
+ import { ZudokuContext } from "../core/ZudokuContext.js";
13
+ import { Slot } from "./Slot.js";
14
+ import { SlotProvider } from "./context/SlotProvider.js";
15
+ import { ZudokuProvider } from "./context/ZudokuProvider.js";
16
+
17
+ /**
18
+ * @vitest-environment happy-dom
19
+ */
20
+
21
+ const createWrapper = (slots: Record<string, ReactNode> = {}) => {
22
+ const queryClient = new QueryClient();
23
+ const context = new ZudokuContext({}, queryClient);
24
+
25
+ const wrapper = ({ children }: PropsWithChildren) => (
26
+ <MemoryRouter initialEntries={["/", "/page"]}>
27
+ <QueryClientProvider client={queryClient}>
28
+ <ZudokuProvider context={context}>
29
+ <SlotProvider slots={slots}>{children}</SlotProvider>
30
+ </ZudokuProvider>
31
+ </QueryClientProvider>
32
+ </MemoryRouter>
33
+ );
34
+
35
+ return { context, wrapper };
36
+ };
37
+
38
+ // We wrap every render function with `act` because of Suspense:
39
+ // https://github.com/testing-library/react-testing-library/issues/1375
40
+ const render = async (
41
+ element: ReactNode,
42
+ slots: Record<string, ReactNode> = {},
43
+ ) => {
44
+ let renderResult: unknown;
45
+ const { wrapper } = createWrapper(slots);
46
+
47
+ await act(async () => {
48
+ renderResult = testRender(element, { wrapper });
49
+ });
50
+
51
+ return renderResult as RenderResult;
52
+ };
53
+
54
+ describe("Slot", () => {
55
+ describe("Slot.Target", () => {
56
+ it("renders fallback when no slot content is provided", async () => {
57
+ await render(
58
+ <Slot.Target
59
+ name="footer-after"
60
+ fallback={<div>Fallback content</div>}
61
+ />,
62
+ );
63
+
64
+ expect(screen.getByText("Fallback content")).toBeInTheDocument();
65
+ });
66
+
67
+ it("renders nothing when no slot content and no fallback", async () => {
68
+ const { container } = await render(<Slot.Target name="footer-after" />);
69
+ expect(container.firstChild).toBeNull();
70
+ });
71
+
72
+ it("renders slot content when provided via SlotProvider", async () => {
73
+ await render(
74
+ <Slot.Target
75
+ name="footer-after"
76
+ fallback={<div>Fallback content</div>}
77
+ />,
78
+ { "footer-after": <div>Provider content</div> },
79
+ );
80
+
81
+ expect(screen.getByText("Provider content")).toBeInTheDocument();
82
+ expect(screen.queryByText("Fallback content")).not.toBeInTheDocument();
83
+ });
84
+ });
85
+
86
+ describe("Slot.Source", () => {
87
+ it("renders content in target slot with replace type (default)", async () => {
88
+ await render(
89
+ <>
90
+ <Slot.Source name="footer-after">
91
+ <div>Source content</div>
92
+ </Slot.Source>
93
+ <Slot.Target
94
+ name="footer-after"
95
+ fallback={<div>Fallback content</div>}
96
+ />
97
+ </>,
98
+ );
99
+
100
+ expect(screen.getByText("Source content")).toBeInTheDocument();
101
+ expect(screen.queryByText("Fallback content")).not.toBeInTheDocument();
102
+ });
103
+
104
+ it("renders content in target slot with explicit replace type", async () => {
105
+ await render(
106
+ <>
107
+ <Slot.Source name="footer-after" type="replace">
108
+ <div>Replace content</div>
109
+ </Slot.Source>
110
+ <Slot.Target name="footer-after" />
111
+ </>,
112
+ );
113
+
114
+ expect(screen.getByText("Replace content")).toBeInTheDocument();
115
+ });
116
+
117
+ it("prepends content when type is prepend", async () => {
118
+ const { container } = await render(
119
+ <>
120
+ <Slot.Source name="footer-after" type="prepend">
121
+ <span>Prepended</span>
122
+ </Slot.Source>
123
+ <Slot.Target name="footer-after" />
124
+ </>,
125
+ {
126
+ "footer-after": <span>Original</span>,
127
+ },
128
+ );
129
+
130
+ expect(container.textContent).toBe("PrependedOriginal");
131
+ });
132
+
133
+ it("appends content when type is append", async () => {
134
+ const { container } = await render(
135
+ <>
136
+ <Slot.Source name="footer-after" type="append">
137
+ <span>Appended</span>
138
+ </Slot.Source>
139
+ <Slot.Target name="footer-after" />
140
+ </>,
141
+ { "footer-after": <span>Original</span> },
142
+ );
143
+
144
+ expect(container.textContent).toBe("OriginalAppended");
145
+ });
146
+
147
+ it("handles multiple sources with different types in correct order", async () => {
148
+ const { container } = await render(
149
+ <>
150
+ <Slot.Source name="footer-after" type="append">
151
+ <span>Appended</span>
152
+ </Slot.Source>
153
+ <Slot.Source name="footer-after" type="prepend">
154
+ <span>Prepended</span>
155
+ </Slot.Source>
156
+ <Slot.Target name="footer-after" />
157
+ </>,
158
+ {
159
+ "footer-after": <span>Original</span>,
160
+ },
161
+ );
162
+
163
+ expect(container.textContent).toBe("PrependedOriginalAppended");
164
+ });
165
+
166
+ it("replaces content when multiple replace sources are provided", async () => {
167
+ await render(
168
+ <>
169
+ <Slot.Source name="footer-after" type="replace">
170
+ <span>First replace</span>
171
+ </Slot.Source>
172
+ <Slot.Source name="footer-after" type="replace">
173
+ <span>Second replace</span>
174
+ </Slot.Source>
175
+ <Slot.Target name="footer-after" />
176
+ </>,
177
+ );
178
+
179
+ expect(screen.getByText("Second replace")).toBeInTheDocument();
180
+ expect(screen.queryByText("First replace")).not.toBeInTheDocument();
181
+ });
182
+
183
+ it("cleans up slot content when component unmounts", async () => {
184
+ const { rerender } = await render(
185
+ <>
186
+ <Slot.Source name="footer-after">
187
+ <div>Source content</div>
188
+ </Slot.Source>
189
+ <Slot.Target
190
+ name="footer-after"
191
+ fallback={<div>Fallback content</div>}
192
+ />
193
+ </>,
194
+ );
195
+
196
+ expect(screen.getByText("Source content")).toBeInTheDocument();
197
+
198
+ rerender(
199
+ <>
200
+ <Slot.Target
201
+ name="footer-after"
202
+ fallback={<div>Fallback content</div>}
203
+ />
204
+ </>,
205
+ );
206
+
207
+ expect(screen.getByText("Fallback content")).toBeInTheDocument();
208
+ expect(screen.queryByText("Source content")).not.toBeInTheDocument();
209
+ });
210
+
211
+ it("handles multiple prepend sources in correct order", async () => {
212
+ const { container } = await render(
213
+ <>
214
+ <Slot.Source name="footer-after" type="prepend">
215
+ <span>First prepend</span>
216
+ </Slot.Source>
217
+ <Slot.Source name="footer-after" type="prepend">
218
+ <span>Second prepend</span>
219
+ </Slot.Source>
220
+ <Slot.Target name="footer-after" />
221
+ </>,
222
+ { "footer-after": <span>Original</span> },
223
+ );
224
+
225
+ expect(container.textContent).toBe("Second prependFirst prependOriginal");
226
+ });
227
+
228
+ it("handles multiple append sources in correct order", async () => {
229
+ const { container } = await render(
230
+ <>
231
+ <Slot.Source name="footer-after" type="append">
232
+ <span>First append</span>
233
+ </Slot.Source>
234
+ <Slot.Source name="footer-after" type="append">
235
+ <span>Second append</span>
236
+ </Slot.Source>
237
+ <Slot.Target name="footer-after" />
238
+ </>,
239
+ { "footer-after": <span>Original</span> },
240
+ );
241
+
242
+ expect(container.textContent).toBe("OriginalFirst appendSecond append");
243
+ });
244
+
245
+ it("handles empty children in Source", async () => {
246
+ const { container } = await render(
247
+ <>
248
+ <Slot.Source name="footer-after">{null}</Slot.Source>
249
+ <Slot.Target name="footer-after" fallback={<span>Fallback</span>} />
250
+ </>,
251
+ );
252
+
253
+ // Empty children should be ignored, showing fallback
254
+ expect(container.textContent).toBe("Fallback");
255
+ });
256
+
257
+ it("renders content when Target is defined before Source", async () => {
258
+ await render(
259
+ <>
260
+ <Slot.Target name="footer-after" />
261
+ <Slot.Source name="footer-after">
262
+ <div>Source content</div>
263
+ </Slot.Source>
264
+ </>,
265
+ );
266
+
267
+ expect(screen.getByText("Source content")).toBeInTheDocument();
268
+ });
269
+
270
+ it("renders content when Source is defined before Target", async () => {
271
+ await render(
272
+ <>
273
+ <Slot.Source name="footer-after">
274
+ <div>Source content</div>
275
+ </Slot.Source>
276
+ <Slot.Target name="footer-after" />
277
+ </>,
278
+ );
279
+
280
+ expect(screen.getByText("Source content")).toBeInTheDocument();
281
+ });
282
+ });
283
+
284
+ describe("Multiple slots", () => {
285
+ it("handles multiple independent slots", async () => {
286
+ await render(
287
+ <>
288
+ <Slot.Source name="footer-before">
289
+ <div>Content 1</div>
290
+ </Slot.Source>
291
+ <Slot.Source name="footer-after">
292
+ <div>Content 2</div>
293
+ </Slot.Source>
294
+ <Slot.Target name="footer-before" />
295
+ <Slot.Target name="footer-after" />
296
+ </>,
297
+ );
298
+
299
+ expect(screen.getByText("Content 1")).toBeInTheDocument();
300
+ expect(screen.getByText("Content 2")).toBeInTheDocument();
301
+ });
302
+
303
+ it("handles slots with same name but different targets", async () => {
304
+ await render(
305
+ <>
306
+ <Slot.Source name="footer-after">
307
+ <div>Shared content</div>
308
+ </Slot.Source>
309
+ <div data-testid="target-1">
310
+ <Slot.Target name="footer-after" />
311
+ </div>
312
+ <div data-testid="target-2">
313
+ <Slot.Target name="footer-after" />
314
+ </div>
315
+ </>,
316
+ );
317
+
318
+ const targets = screen.getAllByText("Shared content");
319
+ expect(targets).toHaveLength(2);
320
+ });
321
+
322
+ it("handles nested slots", async () => {
323
+ await render(
324
+ <>
325
+ <Slot.Source name="content-before">
326
+ <div>
327
+ Outer content
328
+ <Slot.Source name="content-after">
329
+ <div>Inner content</div>
330
+ </Slot.Source>
331
+ </div>
332
+ </Slot.Source>
333
+ <Slot.Target name="content-before" />
334
+ <Slot.Target name="content-after" />
335
+ </>,
336
+ );
337
+
338
+ expect(screen.getByText("Outer content")).toBeInTheDocument();
339
+ expect(screen.getByText("Inner content")).toBeInTheDocument();
340
+ });
341
+ });
342
+
343
+ describe("Edge cases", () => {
344
+ it("handles deep nesting of slots", async () => {
345
+ await render(
346
+ <>
347
+ <Slot.Source name="content-before">
348
+ <div>
349
+ Level 1
350
+ <Slot.Source name="content-after">
351
+ <div>
352
+ Level 2
353
+ <Slot.Source name="navigation-before">
354
+ <div>Level 3</div>
355
+ </Slot.Source>
356
+ </div>
357
+ </Slot.Source>
358
+ </div>
359
+ </Slot.Source>
360
+ <Slot.Target name="content-before" />
361
+ <Slot.Target name="content-after" />
362
+ <Slot.Target name="navigation-before" />
363
+ </>,
364
+ );
365
+
366
+ expect(screen.getByText("Level 1")).toBeInTheDocument();
367
+ expect(screen.getByText("Level 2")).toBeInTheDocument();
368
+ expect(screen.getByText("Level 3")).toBeInTheDocument();
369
+ });
370
+
371
+ it("handles many slots", async () => {
372
+ const manySlots = Array.from({ length: 50 }, (_, i) => `slot-${i}`);
373
+
374
+ await render(
375
+ <>
376
+ {manySlots.map((name) => (
377
+ <Slot.Source key={name} name={name as any}>
378
+ <div>Content {name}</div>
379
+ </Slot.Source>
380
+ ))}
381
+ {manySlots.map((name) => (
382
+ <Slot.Target key={name} name={name as any} />
383
+ ))}
384
+ </>,
385
+ );
386
+
387
+ manySlots.forEach((name) => {
388
+ expect(screen.getByText(`Content ${name}`)).toBeInTheDocument();
389
+ });
390
+ });
391
+ });
392
+
393
+ describe("Integration cases", () => {
394
+ it("handles updates", async () => {
395
+ const { rerender } = await render(
396
+ <>
397
+ <Slot.Source name="content-before">
398
+ <div>Initial content</div>
399
+ </Slot.Source>
400
+ <Slot.Target name="content-before" />
401
+ </>,
402
+ );
403
+
404
+ expect(screen.getByText("Initial content")).toBeInTheDocument();
405
+
406
+ rerender(
407
+ <>
408
+ <Slot.Source name="content-before">
409
+ <div>Updated content</div>
410
+ </Slot.Source>
411
+ <Slot.Target name="content-before" />
412
+ </>,
413
+ );
414
+
415
+ expect(screen.getByText("Updated content")).toBeInTheDocument();
416
+ });
417
+
418
+ it("handles async content", async () => {
419
+ vi.useFakeTimers();
420
+
421
+ const AsyncContent = () => {
422
+ const [content, setContent] = useState("Loading...");
423
+
424
+ useEffect(() => {
425
+ setTimeout(() => setContent("Loaded content"), 250);
426
+ }, []);
427
+
428
+ return <div>{content}</div>;
429
+ };
430
+
431
+ await render(
432
+ <>
433
+ <Slot.Source name="content-before">
434
+ <AsyncContent />
435
+ </Slot.Source>
436
+ <Slot.Target name="content-before" />
437
+ </>,
438
+ );
439
+
440
+ expect(screen.getByText("Loading...")).toBeInTheDocument();
441
+
442
+ await act(async () => {
443
+ vi.advanceTimersToNextTimer();
444
+ });
445
+
446
+ expect(screen.getByText("Loaded content")).toBeInTheDocument();
447
+
448
+ vi.useRealTimers();
449
+ });
450
+
451
+ it("renders render functions", async () => {
452
+ await render(
453
+ <>
454
+ <Slot.Source name="content-before">
455
+ {(props) => `Current path: ${props.location.pathname}`}
456
+ </Slot.Source>
457
+ <Slot.Target name="content-before" />
458
+ </>,
459
+ {},
460
+ );
461
+
462
+ expect(screen.getByText("Current path: /page")).toBeInTheDocument();
463
+ });
464
+ });
465
+ });
@@ -0,0 +1,64 @@
1
+ import { useId, useLayoutEffect, type ReactNode } from "react";
2
+ import {
3
+ useRenderSlot,
4
+ useSlotContext,
5
+ type SlotType,
6
+ } from "./context/SlotProvider.js";
7
+
8
+ // This is to augment the type of the Slot component with custom slot names
9
+ // This is useful for plugins to add custom slots to the Zudoku context
10
+ // and for the user to use them in their own components
11
+ export type CustomSlotNames = never;
12
+
13
+ type PredefinedSlotNames =
14
+ | "api-keys-list-page"
15
+ | "api-keys-list-page-before-keys"
16
+ | "footer-after"
17
+ | "footer-before"
18
+ | "head-navigation-end"
19
+ | "head-navigation-start"
20
+ | "layout-after-head"
21
+ | "layout-before-head"
22
+ | "top-navigation-after"
23
+ | "top-navigation-before"
24
+ | "top-navigation-side"
25
+ | "content-before"
26
+ | "content-after"
27
+ | "navigation-after"
28
+ | "navigation-before";
29
+
30
+ export type SlotName = PredefinedSlotNames | CustomSlotNames;
31
+
32
+ export const Slot = {
33
+ Source: ({
34
+ name,
35
+ children,
36
+ type = "replace",
37
+ }: {
38
+ name: SlotName;
39
+ type?: "prepend" | "replace" | "append";
40
+ children: SlotType;
41
+ }) => {
42
+ const id = useId();
43
+ const setSlot = useSlotContext((s) => s.setSlot);
44
+ const clearSlot = useSlotContext((s) => s.clearSlot);
45
+
46
+ if (import.meta.env.SSR) {
47
+ setSlot(id, name, children, type);
48
+ }
49
+
50
+ useLayoutEffect(() => {
51
+ setSlot(id, name, children, type);
52
+ return () => clearSlot(id, name);
53
+ }, [id, name, children, type, setSlot, clearSlot]);
54
+
55
+ return null;
56
+ },
57
+
58
+ Target: ({ name, fallback }: { name: string; fallback?: ReactNode }) => {
59
+ const slot = useRenderSlot(name);
60
+
61
+ if (slot.length === 0) return fallback;
62
+ return slot;
63
+ },
64
+ };
@@ -2,24 +2,12 @@ import { useNProgress } from "@tanem/react-nprogress";
2
2
  import { cx } from "class-variance-authority";
3
3
  import { Suspense, useEffect, useState } from "react";
4
4
  import { NavLink, useNavigation } from "react-router";
5
- import type { TopNavigationItem } from "../../config/validators/common.js";
5
+ import type { TopNavigationItem } from "../../config/validators/validate.js";
6
6
  import { useAuth } from "../authentication/hook.js";
7
7
  import { joinUrl } from "../util/joinUrl.js";
8
8
  import { useCurrentNavigation, useZudoku } from "./context/ZudokuContext.js";
9
- import { traverseSidebar } from "./navigation/utils.js";
10
- import { Slotlet } from "./SlotletProvider.js";
11
-
12
- export const isHiddenItem =
13
- (isAuthenticated?: boolean) =>
14
- (item: { display?: "auth" | "anon" | "always" | "hide" }): boolean => {
15
- if (item.display === "hide") return false;
16
- return (
17
- (item.display === "auth" && isAuthenticated) ||
18
- (item.display === "anon" && !isAuthenticated) ||
19
- !item.display ||
20
- item.display === "always"
21
- );
22
- };
9
+ import { isHiddenItem, traverseSidebar } from "./navigation/utils.js";
10
+ import { Slot } from "./Slot.js";
23
11
 
24
12
  export const PageProgress = () => {
25
13
  const navigation = useNavigation();
@@ -58,7 +46,7 @@ export const TopNavigation = () => {
58
46
 
59
47
  return (
60
48
  <Suspense>
61
- <div className="items-center justify-between px-8 h-[--top-nav-height] hidden lg:flex text-sm relative">
49
+ <div className="items-center justify-between px-8 h-(--top-nav-height) hidden lg:flex text-sm relative">
62
50
  <nav className="text-sm">
63
51
  <ul className="flex flex-row items-center gap-8">
64
52
  {filteredItems.map((item) => (
@@ -68,7 +56,7 @@ export const TopNavigation = () => {
68
56
  ))}
69
57
  </ul>
70
58
  </nav>
71
- <Slotlet name="top-navigation-side" />
59
+ <Slot.Target name="top-navigation-side" />
72
60
  </div>
73
61
  <PageProgress />
74
62
  </Suspense>
@@ -26,9 +26,9 @@ import {
26
26
  DEFAULT_COMPONENTS,
27
27
  } from "./context/ComponentsContext.js";
28
28
  import { RouterEventsEmitter } from "./context/RouterEventsEmitter.js";
29
+ import { SlotProvider } from "./context/SlotProvider.js";
29
30
  import { ViewportAnchorProvider } from "./context/ViewportAnchorContext.js";
30
31
  import { ZudokuProvider } from "./context/ZudokuProvider.js";
31
- import { SlotletProvider } from "./SlotletProvider.js";
32
32
 
33
33
  let zudokuContext: ZudokuContext | undefined;
34
34
 
@@ -87,17 +87,17 @@ const ZudokoInner = memo(
87
87
  <StaggeredRenderContext.Provider value={staggeredValue}>
88
88
  <ZudokuProvider context={zudokuContext}>
89
89
  <RouterEventsEmitter />
90
- <MDXProvider components={mdxComponents}>
91
- <ThemeProvider attribute="class" disableTransitionOnChange>
92
- <ComponentsProvider value={components}>
93
- <SlotletProvider slotlets={props.slotlets}>
90
+ <SlotProvider slots={props.slots ?? props.UNSAFE_slotlets}>
91
+ <MDXProvider components={mdxComponents}>
92
+ <ThemeProvider attribute="class" disableTransitionOnChange>
93
+ <ComponentsProvider value={components}>
94
94
  <ViewportAnchorProvider>
95
95
  {children ?? <Outlet />}
96
96
  </ViewportAnchorProvider>
97
- </SlotletProvider>
98
- </ComponentsProvider>
99
- </ThemeProvider>
100
- </MDXProvider>
97
+ </ComponentsProvider>
98
+ </ThemeProvider>
99
+ </MDXProvider>
100
+ </SlotProvider>
101
101
  </ZudokuProvider>
102
102
  </StaggeredRenderContext.Provider>
103
103
  </>