@redocly/theme 0.70.0-next.1 → 0.70.0-next.11

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 (378) hide show
  1. package/lib/components/Buttons/ConnectMCPButton.js +19 -14
  2. package/lib/components/Buttons/variables.d.ts +1 -0
  3. package/lib/components/Buttons/variables.js +4 -1
  4. package/lib/components/Catalog/Catalog.js +3 -3
  5. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.d.ts +1 -1
  6. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js +1 -1
  7. package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
  8. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
  9. package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +30 -11
  10. package/lib/components/Catalog/CatalogFilter/CatalogFilterDateRange.js +2 -1
  11. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
  12. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
  13. package/lib/components/CodeBlock/CodeBlockControls.js +3 -5
  14. package/lib/components/Consent/Consent.d.ts +2 -0
  15. package/lib/components/Consent/Consent.js +17 -0
  16. package/lib/components/Consent/ConsentBanner.d.ts +2 -0
  17. package/lib/components/Consent/ConsentBanner.js +120 -0
  18. package/lib/components/Consent/ConsentDialog.d.ts +2 -0
  19. package/lib/components/Consent/ConsentDialog.js +128 -0
  20. package/lib/components/Consent/ConsentSettingsLink.d.ts +2 -0
  21. package/lib/components/Consent/ConsentSettingsLink.js +35 -0
  22. package/lib/components/Consent/variables.d.ts +1 -0
  23. package/lib/components/Consent/variables.js +31 -0
  24. package/lib/components/Dropdown/Dropdown.d.ts +4 -2
  25. package/lib/components/Dropdown/Dropdown.js +31 -9
  26. package/lib/components/Dropdown/DropdownMenu.d.ts +1 -0
  27. package/lib/components/Dropdown/DropdownMenu.js +1 -1
  28. package/lib/components/Feedback/Reasons.js +3 -2
  29. package/lib/components/Filter/FilterCheckboxes.js +30 -11
  30. package/lib/components/Filter/FilterDateRange.js +36 -2
  31. package/lib/components/Footer/Footer.js +4 -1
  32. package/lib/components/Image/Image.js +24 -4
  33. package/lib/components/JsonViewer/Helpers.d.ts +10 -2
  34. package/lib/components/JsonViewer/Helpers.js +32 -36
  35. package/lib/components/JsonViewer/JsonViewer.js +15 -18
  36. package/lib/components/LoadProgressBar/LoadProgressBar.d.ts +8 -0
  37. package/lib/components/LoadProgressBar/LoadProgressBar.js +122 -0
  38. package/lib/components/MCP/McpConnectionTabs.js +9 -2
  39. package/lib/components/Markdown/Markdown.js +3 -2
  40. package/lib/components/Markdown/styles/base-table.js +14 -1
  41. package/lib/components/Markdown/variables.js +1 -0
  42. package/lib/components/Menu/Menu.js +4 -0
  43. package/lib/components/Menu/MenuSelect.d.ts +7 -0
  44. package/lib/components/Menu/MenuSelect.js +129 -0
  45. package/lib/components/Menu/variables.js +43 -4
  46. package/lib/components/Navbar/Navbar.js +44 -5
  47. package/lib/components/Navbar/variables.js +3 -0
  48. package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
  49. package/lib/components/NavigationTabs/NavigationTab.js +93 -0
  50. package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
  51. package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
  52. package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
  53. package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
  54. package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
  55. package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
  56. package/lib/components/NavigationTabs/variables.d.ts +1 -0
  57. package/lib/components/NavigationTabs/variables.js +37 -0
  58. package/lib/components/Portal/Portal.js +37 -5
  59. package/lib/components/Product/utils.js +1 -1
  60. package/lib/components/Search/SearchAiActionButtons.js +8 -3
  61. package/lib/components/Search/SearchAiActivity.d.ts +10 -0
  62. package/lib/components/Search/SearchAiActivity.js +278 -0
  63. package/lib/components/Search/SearchAiConversationInput.js +10 -6
  64. package/lib/components/Search/SearchAiDialog.js +13 -2
  65. package/lib/components/Search/SearchAiMessage.d.ts +2 -1
  66. package/lib/components/Search/SearchAiMessage.js +21 -109
  67. package/lib/components/Search/SearchAiResponse.js +1 -0
  68. package/lib/components/Search/SearchDialog.js +10 -0
  69. package/lib/components/Search/SearchItem.js +11 -10
  70. package/lib/components/Search/SearchTrigger.js +37 -6
  71. package/lib/components/Search/variables.js +17 -2
  72. package/lib/components/Segmented/Segmented.js +23 -3
  73. package/lib/components/Select/Select.js +10 -3
  74. package/lib/components/Select/SelectInput.d.ts +1 -0
  75. package/lib/components/Select/SelectInput.js +5 -11
  76. package/lib/components/Sidebar/Sidebar.js +2 -2
  77. package/lib/components/SplitButton/SplitButton.js +37 -3
  78. package/lib/components/TableOfContent/TableOfContent.js +2 -2
  79. package/lib/core/constants/common.d.ts +1 -0
  80. package/lib/core/constants/common.js +1 -0
  81. package/lib/core/constants/consent.d.ts +2 -0
  82. package/lib/core/constants/consent.js +30 -0
  83. package/lib/core/constants/index.d.ts +2 -0
  84. package/lib/core/constants/index.js +2 -0
  85. package/lib/core/constants/mcp.d.ts +2 -2
  86. package/lib/core/constants/mcp.js +3 -8
  87. package/lib/core/constants/prompt.d.ts +9 -0
  88. package/lib/core/constants/prompt.js +33 -0
  89. package/lib/core/constants/search.d.ts +1 -1
  90. package/lib/core/constants/search.js +6 -2
  91. package/lib/core/contexts/PortalContainerContext.d.ts +2 -0
  92. package/lib/core/contexts/PortalContainerContext.js +7 -0
  93. package/lib/core/hooks/code-walkthrough/use-code-panel.d.ts +1 -1
  94. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +1 -1
  95. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +1 -1
  96. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +1 -1
  97. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +1 -2
  98. package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +1 -1
  99. package/lib/core/hooks/index.d.ts +9 -0
  100. package/lib/core/hooks/index.js +9 -0
  101. package/lib/core/hooks/menu/use-collapse.js +1 -1
  102. package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
  103. package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
  104. package/lib/core/hooks/prompt/use-prompt-actions.d.ts +7 -0
  105. package/lib/core/hooks/prompt/use-prompt-actions.js +19 -0
  106. package/lib/core/hooks/prompt/use-prompt-text-limit.d.ts +19 -0
  107. package/lib/core/hooks/prompt/use-prompt-text-limit.js +35 -0
  108. package/lib/core/hooks/search/use-persisted-quick-filter.d.ts +21 -0
  109. package/lib/core/hooks/search/use-persisted-quick-filter.js +92 -0
  110. package/lib/core/hooks/search/use-search-ai-activity.d.ts +11 -0
  111. package/lib/core/hooks/search/use-search-ai-activity.js +15 -0
  112. package/lib/core/hooks/use-connect-mcp-button.js +3 -1
  113. package/lib/core/hooks/use-consent-dialog.d.ts +12 -0
  114. package/lib/core/hooks/use-consent-dialog.js +36 -0
  115. package/lib/core/hooks/use-consent-telemetry.d.ts +1 -0
  116. package/lib/core/hooks/use-consent-telemetry.js +42 -0
  117. package/lib/core/hooks/use-dialog-hotkeys.js +4 -2
  118. package/lib/core/hooks/use-full-height.d.ts +1 -1
  119. package/lib/core/hooks/use-full-height.js +8 -8
  120. package/lib/core/hooks/use-page-actions.d.ts +1 -1
  121. package/lib/core/hooks/use-page-actions.js +10 -8
  122. package/lib/core/hooks/use-pointer-border-highlight.d.ts +7 -0
  123. package/lib/core/hooks/use-pointer-border-highlight.js +29 -0
  124. package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
  125. package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
  126. package/lib/core/hooks/use-tab-list.d.ts +31 -0
  127. package/lib/core/hooks/use-tab-list.js +49 -0
  128. package/lib/core/hooks/use-telemetry-fallback.d.ts +2 -0
  129. package/lib/core/hooks/use-telemetry-fallback.js +2 -0
  130. package/lib/core/hooks/use-theme-hooks.js +16 -0
  131. package/lib/core/styles/dark.js +14 -12
  132. package/lib/core/styles/global.d.ts +2 -0
  133. package/lib/core/styles/global.js +115 -136
  134. package/lib/core/styles/index.d.ts +1 -0
  135. package/lib/core/styles/index.js +3 -1
  136. package/lib/core/styles/search-ai-appear.d.ts +1 -0
  137. package/lib/core/styles/search-ai-appear.js +18 -0
  138. package/lib/core/types/code-walkthrough.d.ts +84 -0
  139. package/lib/core/types/consent.d.ts +54 -0
  140. package/lib/core/types/consent.js +3 -0
  141. package/lib/core/types/dropdown.d.ts +1 -0
  142. package/lib/core/types/dropdown.js +3 -0
  143. package/lib/core/types/hooks.d.ts +8 -1
  144. package/lib/core/types/index.d.ts +4 -0
  145. package/lib/core/types/l10n.d.ts +1 -1
  146. package/lib/core/types/mcp.d.ts +3 -2
  147. package/lib/core/types/navigation-tabs.d.ts +49 -0
  148. package/lib/core/types/navigation-tabs.js +3 -0
  149. package/lib/core/types/prompt.d.ts +9 -0
  150. package/lib/core/types/prompt.js +3 -0
  151. package/lib/core/types/search.d.ts +25 -0
  152. package/lib/core/utils/Dynamic.d.ts +8 -1
  153. package/lib/core/utils/Dynamic.js +34 -3
  154. package/lib/core/utils/assign-ref.d.ts +2 -0
  155. package/lib/core/utils/assign-ref.js +12 -0
  156. package/lib/core/utils/consent-settings-link-placement.d.ts +3 -0
  157. package/lib/core/utils/consent-settings-link-placement.js +15 -0
  158. package/lib/core/utils/content-segments.d.ts +12 -1
  159. package/lib/core/utils/content-segments.js +90 -5
  160. package/lib/core/utils/download-code-walkthrough.d.ts +1 -1
  161. package/lib/core/utils/dropdown.d.ts +2 -0
  162. package/lib/core/utils/dropdown.js +12 -0
  163. package/lib/core/utils/get-ai-prompt-link.d.ts +15 -0
  164. package/lib/core/utils/get-ai-prompt-link.js +29 -0
  165. package/lib/core/utils/get-code-walkthrough-file-text.d.ts +1 -1
  166. package/lib/core/utils/index.d.ts +5 -0
  167. package/lib/core/utils/index.js +5 -0
  168. package/lib/core/utils/match-code-walkthrough-conditions.d.ts +1 -1
  169. package/lib/core/utils/mcp.d.ts +2 -1
  170. package/lib/core/utils/mcp.js +13 -3
  171. package/lib/core/utils/menu.d.ts +4 -0
  172. package/lib/core/utils/menu.js +48 -8
  173. package/lib/core/utils/navigation-tabs.d.ts +8 -0
  174. package/lib/core/utils/navigation-tabs.js +71 -0
  175. package/lib/core/utils/search-ai-activity.d.ts +4 -0
  176. package/lib/core/utils/search-ai-activity.js +83 -0
  177. package/lib/core/utils/urls.js +3 -1
  178. package/lib/core/utils/with-load-progress.d.ts +3 -0
  179. package/lib/core/utils/with-load-progress.js +24 -19
  180. package/lib/ext/configure.d.ts +1 -1
  181. package/lib/ext/configure.js +0 -1
  182. package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.d.ts +29 -0
  183. package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.js +81 -0
  184. package/lib/icons/LinkIcon/LinkIconSymbol.d.ts +12 -0
  185. package/lib/icons/LinkIcon/LinkIconSymbol.js +41 -0
  186. package/lib/index.d.ts +7 -0
  187. package/lib/index.js +9 -1
  188. package/lib/layouts/PageLayout.js +1 -1
  189. package/lib/layouts/RootLayout.js +2 -2
  190. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.d.ts +1 -1
  191. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
  192. package/lib/markdoc/components/CodeWalkthrough/CodePanel.d.ts +1 -1
  193. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
  194. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.d.ts +1 -1
  195. package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.d.ts +1 -1
  196. package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +1 -1
  197. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.d.ts +1 -1
  198. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
  199. package/lib/markdoc/components/Prompt/Prompt.d.ts +15 -0
  200. package/lib/markdoc/components/Prompt/Prompt.js +163 -0
  201. package/lib/markdoc/components/Prompt/PromptActions.d.ts +13 -0
  202. package/lib/markdoc/components/Prompt/PromptActions.js +43 -0
  203. package/lib/markdoc/components/Prompt/PromptBody.d.ts +14 -0
  204. package/lib/markdoc/components/Prompt/PromptBody.js +99 -0
  205. package/lib/markdoc/components/Prompt/PromptCopyButton.d.ts +10 -0
  206. package/lib/markdoc/components/Prompt/PromptCopyButton.js +28 -0
  207. package/lib/markdoc/components/Prompt/PromptHeader.d.ts +9 -0
  208. package/lib/markdoc/components/Prompt/PromptHeader.js +57 -0
  209. package/lib/markdoc/components/Prompt/PromptShowHideButton.d.ts +7 -0
  210. package/lib/markdoc/components/Prompt/PromptShowHideButton.js +21 -0
  211. package/lib/markdoc/components/Prompt/PromptToggleLabel.d.ts +7 -0
  212. package/lib/markdoc/components/Prompt/PromptToggleLabel.js +28 -0
  213. package/lib/markdoc/components/Prompt/variables.d.ts +1 -0
  214. package/lib/markdoc/components/Prompt/variables.dark.d.ts +1 -0
  215. package/lib/markdoc/components/Prompt/variables.dark.js +8 -0
  216. package/lib/markdoc/components/Prompt/variables.js +44 -0
  217. package/lib/markdoc/components/Tabs/TabList.js +8 -6
  218. package/lib/markdoc/components/default.d.ts +1 -0
  219. package/lib/markdoc/components/default.js +1 -0
  220. package/lib/markdoc/default.d.ts +2 -0
  221. package/lib/markdoc/default.js +2 -0
  222. package/lib/markdoc/tags/code-walkthrough.d.ts +1 -1
  223. package/lib/markdoc/tags/connect-mcp.js +15 -0
  224. package/lib/markdoc/tags/prompt.d.ts +2 -0
  225. package/lib/markdoc/tags/prompt.js +56 -0
  226. package/package.json +4 -8
  227. package/src/components/Buttons/ConnectMCPButton.tsx +21 -16
  228. package/src/components/Buttons/variables.ts +4 -0
  229. package/src/components/Catalog/Catalog.tsx +6 -4
  230. package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.tsx +3 -1
  231. package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
  232. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
  233. package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +37 -22
  234. package/src/components/Catalog/CatalogFilter/CatalogFilterDateRange.tsx +3 -2
  235. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
  236. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
  237. package/src/components/CodeBlock/CodeBlockControls.tsx +4 -7
  238. package/src/components/Consent/Consent.tsx +18 -0
  239. package/src/components/Consent/ConsentBanner.tsx +110 -0
  240. package/src/components/Consent/ConsentDialog.tsx +210 -0
  241. package/src/components/Consent/ConsentSettingsLink.tsx +44 -0
  242. package/src/components/Consent/variables.ts +28 -0
  243. package/src/components/Dropdown/Dropdown.tsx +32 -7
  244. package/src/components/Dropdown/DropdownMenu.tsx +7 -1
  245. package/src/components/Feedback/Reasons.tsx +3 -2
  246. package/src/components/Filter/FilterCheckboxes.tsx +33 -18
  247. package/src/components/Filter/FilterDateRange.tsx +3 -2
  248. package/src/components/Footer/Footer.tsx +2 -0
  249. package/src/components/Image/Image.tsx +26 -5
  250. package/src/components/JsonViewer/Helpers.tsx +51 -54
  251. package/src/components/JsonViewer/JsonViewer.tsx +23 -25
  252. package/src/components/LoadProgressBar/LoadProgressBar.tsx +113 -0
  253. package/src/components/MCP/McpConnectionTabs.tsx +22 -5
  254. package/src/components/Markdown/Markdown.tsx +3 -2
  255. package/src/components/Markdown/styles/base-table.ts +14 -1
  256. package/src/components/Markdown/variables.ts +1 -0
  257. package/src/components/Menu/Menu.tsx +5 -0
  258. package/src/components/Menu/MenuSelect.tsx +198 -0
  259. package/src/components/Menu/variables.ts +43 -4
  260. package/src/components/Navbar/Navbar.tsx +22 -5
  261. package/src/components/Navbar/variables.ts +3 -0
  262. package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
  263. package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
  264. package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
  265. package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
  266. package/src/components/NavigationTabs/variables.ts +34 -0
  267. package/src/components/Portal/Portal.tsx +4 -2
  268. package/src/components/Product/utils.ts +1 -1
  269. package/src/components/Search/SearchAiActionButtons.tsx +31 -19
  270. package/src/components/Search/SearchAiActivity.tsx +318 -0
  271. package/src/components/Search/SearchAiConversationInput.tsx +13 -7
  272. package/src/components/Search/SearchAiDialog.tsx +20 -4
  273. package/src/components/Search/SearchAiMessage.tsx +28 -136
  274. package/src/components/Search/SearchAiResponse.tsx +1 -0
  275. package/src/components/Search/SearchDialog.tsx +11 -0
  276. package/src/components/Search/SearchItem.tsx +19 -10
  277. package/src/components/Search/SearchTrigger.tsx +47 -3
  278. package/src/components/Search/variables.ts +17 -2
  279. package/src/components/Segmented/Segmented.tsx +25 -16
  280. package/src/components/Select/Select.tsx +12 -6
  281. package/src/components/Select/SelectInput.tsx +10 -18
  282. package/src/components/Sidebar/Sidebar.tsx +2 -2
  283. package/src/components/SplitButton/SplitButton.tsx +8 -2
  284. package/src/components/TableOfContent/TableOfContent.tsx +2 -2
  285. package/src/core/constants/common.ts +1 -0
  286. package/src/core/constants/consent.ts +29 -0
  287. package/src/core/constants/index.ts +2 -0
  288. package/src/core/constants/mcp.ts +3 -9
  289. package/src/core/constants/prompt.ts +34 -0
  290. package/src/core/constants/search.ts +6 -2
  291. package/src/core/contexts/PortalContainerContext.tsx +4 -0
  292. package/src/core/hooks/__mocks__/index.ts +5 -0
  293. package/src/core/hooks/__mocks__/use-theme-hooks.ts +20 -0
  294. package/src/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.ts +1 -2
  295. package/src/core/hooks/code-walkthrough/__mocks__/mock-intersection-observer.ts +1 -2
  296. package/src/core/hooks/code-walkthrough/use-code-panel.ts +1 -1
  297. package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +2 -2
  298. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -1
  299. package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +3 -3
  300. package/src/core/hooks/code-walkthrough/use-renderable-files.ts +1 -1
  301. package/src/core/hooks/index.ts +9 -0
  302. package/src/core/hooks/menu/use-collapse.ts +1 -1
  303. package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
  304. package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
  305. package/src/core/hooks/prompt/use-prompt-actions.ts +28 -0
  306. package/src/core/hooks/prompt/use-prompt-text-limit.ts +59 -0
  307. package/src/core/hooks/search/use-persisted-quick-filter.ts +125 -0
  308. package/src/core/hooks/search/use-search-ai-activity.ts +31 -0
  309. package/src/core/hooks/use-connect-mcp-button.ts +13 -2
  310. package/src/core/hooks/use-consent-dialog.ts +51 -0
  311. package/src/core/hooks/use-consent-telemetry.ts +56 -0
  312. package/src/core/hooks/use-dialog-hotkeys.ts +11 -5
  313. package/src/core/hooks/use-full-height.ts +8 -8
  314. package/src/core/hooks/use-page-actions.ts +21 -9
  315. package/src/core/hooks/use-pointer-border-highlight.ts +46 -0
  316. package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
  317. package/src/core/hooks/use-tab-list.ts +63 -0
  318. package/src/core/hooks/use-telemetry-fallback.ts +2 -0
  319. package/src/core/hooks/use-theme-hooks.ts +16 -0
  320. package/src/core/styles/dark.ts +2 -0
  321. package/src/core/styles/global.ts +96 -116
  322. package/src/core/styles/index.ts +2 -1
  323. package/src/core/styles/search-ai-appear.ts +16 -0
  324. package/src/core/types/code-walkthrough.ts +103 -0
  325. package/src/core/types/consent.ts +51 -0
  326. package/src/core/types/dropdown.ts +1 -0
  327. package/src/core/types/hooks.ts +8 -0
  328. package/src/core/types/index.ts +4 -0
  329. package/src/core/types/l10n.ts +46 -2
  330. package/src/core/types/mcp.ts +4 -2
  331. package/src/core/types/navigation-tabs.ts +54 -0
  332. package/src/core/types/prompt.ts +11 -0
  333. package/src/core/types/search.ts +23 -0
  334. package/src/core/utils/Dynamic.tsx +67 -35
  335. package/src/core/utils/assign-ref.ts +9 -0
  336. package/src/core/utils/consent-settings-link-placement.ts +18 -0
  337. package/src/core/utils/content-segments.ts +98 -6
  338. package/src/core/utils/download-code-walkthrough.ts +1 -1
  339. package/src/core/utils/dropdown.ts +14 -0
  340. package/src/core/utils/get-ai-prompt-link.ts +30 -0
  341. package/src/core/utils/get-code-walkthrough-file-text.ts +1 -1
  342. package/src/core/utils/index.ts +5 -0
  343. package/src/core/utils/match-code-walkthrough-conditions.ts +1 -1
  344. package/src/core/utils/mcp.ts +16 -4
  345. package/src/core/utils/menu.ts +54 -9
  346. package/src/core/utils/navigation-tabs.ts +99 -0
  347. package/src/core/utils/search-ai-activity.ts +110 -0
  348. package/src/core/utils/urls.ts +3 -1
  349. package/src/core/utils/with-load-progress.ts +23 -18
  350. package/src/ext/configure.ts +1 -1
  351. package/src/icons/CheckboxIcon/CheckboxIcon.tsx +1 -0
  352. package/src/icons/ChevronSortIcon/ChevronSortIcon.tsx +1 -0
  353. package/src/icons/ExpandCollapseIcon/ExpandCollapseIcon.tsx +56 -0
  354. package/src/icons/LinkIcon/LinkIconSymbol.tsx +51 -0
  355. package/src/index.ts +8 -0
  356. package/src/layouts/PageLayout.tsx +1 -1
  357. package/src/layouts/RootLayout.tsx +2 -2
  358. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +2 -2
  359. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +4 -4
  360. package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +1 -1
  361. package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +1 -1
  362. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +1 -1
  363. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +2 -2
  364. package/src/markdoc/components/Prompt/Prompt.tsx +219 -0
  365. package/src/markdoc/components/Prompt/PromptActions.tsx +104 -0
  366. package/src/markdoc/components/Prompt/PromptBody.tsx +107 -0
  367. package/src/markdoc/components/Prompt/PromptCopyButton.tsx +73 -0
  368. package/src/markdoc/components/Prompt/PromptHeader.tsx +81 -0
  369. package/src/markdoc/components/Prompt/PromptShowHideButton.tsx +43 -0
  370. package/src/markdoc/components/Prompt/PromptToggleLabel.tsx +41 -0
  371. package/src/markdoc/components/Prompt/variables.dark.ts +5 -0
  372. package/src/markdoc/components/Prompt/variables.ts +41 -0
  373. package/src/markdoc/components/Tabs/TabList.tsx +9 -12
  374. package/src/markdoc/components/default.ts +1 -0
  375. package/src/markdoc/default.ts +2 -0
  376. package/src/markdoc/tags/code-walkthrough.ts +1 -1
  377. package/src/markdoc/tags/connect-mcp.ts +16 -1
  378. package/src/markdoc/tags/prompt.ts +58 -0
@@ -5,7 +5,8 @@ import type { JSX } from 'react';
5
5
  import type { CodeBlockControlsProps } from '@redocly/theme/components/CodeBlock/CodeBlockControls';
6
6
 
7
7
  import { CodeBlock } from '@redocly/theme/components/CodeBlock/CodeBlock';
8
- import { JsonValue } from '@redocly/theme/components/JsonViewer/Helpers';
8
+ import { collectFoldables, JsonValue } from '@redocly/theme/components/JsonViewer/Helpers';
9
+ import type { JsonFold } from '@redocly/theme/components/JsonViewer/Helpers';
9
10
 
10
11
  export type PanelType = 'request' | 'responses' | 'request-samples' | 'response-samples';
11
12
 
@@ -33,25 +34,20 @@ function JsonComponent({
33
34
  controls = {},
34
35
  maxStringLength,
35
36
  }: JsonProps): JSX.Element {
36
- const showFoldingButtons =
37
- data && Object.values(data).some((value) => typeof value === 'object' && value !== null);
37
+ const defaultExpandLevel = Math.max(1, expandLevel);
38
+ const foldables = React.useMemo(() => collectFoldables(data), [data]);
39
+ const [expandedPaths, setExpandedPaths] = React.useState<Record<string, boolean>>({});
38
40
 
39
- const [expandAllSignal, setExpandAllSignal] = React.useState<boolean | undefined>(undefined);
40
-
41
- const expandAll = () => {
42
- setExpandAllSignal(true);
43
- onPanelToggle?.(true);
44
- setTimeout(() => {
45
- setExpandAllSignal(undefined);
46
- });
41
+ const fold: JsonFold = {
42
+ isExpanded: (path, level) => expandedPaths[path] ?? level < defaultExpandLevel,
43
+ setExpanded: (path, expanded) => setExpandedPaths((prev) => ({ ...prev, [path]: expanded })),
47
44
  };
45
+ const hasFoldables = foldables.length > 0;
46
+ const allExpanded = foldables.every(([path, level]) => fold.isExpanded(path, level));
48
47
 
49
- const collapseAll = () => {
50
- setExpandAllSignal(false);
51
- onPanelToggle?.(false);
52
- setTimeout(() => {
53
- setExpandAllSignal(undefined);
54
- });
48
+ const toggleAll = () => {
49
+ onPanelToggle?.(!allExpanded);
50
+ setExpandedPaths(Object.fromEntries(foldables.map(([path]) => [path, !allExpanded])));
55
51
  };
56
52
 
57
53
  const source = JSON.stringify(data, null, 2);
@@ -73,12 +69,14 @@ function JsonComponent({
73
69
  controls: controls && {
74
70
  ...controls,
75
71
  copy: { ...controls.copy, data, onClick: onCopyClick, handleOutside: true },
76
- expand: showFoldingButtons
77
- ? { ...controls.expand, onClick: expandAll }
78
- : undefined,
79
- collapse: showFoldingButtons
80
- ? { ...controls.collapse, onClick: collapseAll }
81
- : undefined,
72
+ expand:
73
+ hasFoldables && !allExpanded
74
+ ? { ...controls.expand, onClick: toggleAll }
75
+ : undefined,
76
+ collapse:
77
+ hasFoldables && allExpanded
78
+ ? { ...controls.collapse, onClick: toggleAll }
79
+ : undefined,
82
80
  },
83
81
  }
84
82
  : undefined
@@ -89,9 +87,9 @@ function JsonComponent({
89
87
  <JsonValue
90
88
  value={data}
91
89
  level={0}
90
+ path=""
92
91
  standalone={true}
93
- expandAllSignal={expandAllSignal}
94
- defaultExpandLevel={Math.max(1, expandLevel)}
92
+ fold={fold}
95
93
  maxStringLength={maxStringLength}
96
94
  />
97
95
  </FoldingWrap>
@@ -0,0 +1,113 @@
1
+ import React, { useEffect, useRef, useState, useSyncExternalStore } from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { JSX } from 'react';
5
+
6
+ import { isLoadInProgress, subscribeToLoadProgress } from '@redocly/theme/core/utils';
7
+
8
+ export type LoadProgressBarProps = {
9
+ /** Also shows the bar while the host's own navigation is pending. */
10
+ pending?: boolean;
11
+ className?: string;
12
+ };
13
+
14
+ const START = 0.08;
15
+ const MAX_PENDING = 0.994;
16
+ const TRICKLE_MS = 100;
17
+ const SETTLE_MS = 200;
18
+ // [below, step]: large steps at first, smaller ones near the end.
19
+ const TRICKLE_STEPS = [
20
+ [0.2, 0.1],
21
+ [0.5, 0.04],
22
+ [0.8, 0.02],
23
+ [0.99, 0.005],
24
+ ] as const;
25
+
26
+ function trickle(progress: number): number {
27
+ const step = TRICKLE_STEPS.find(([below]) => progress < below)?.[1] ?? 0;
28
+ return Math.min(progress + step, MAX_PENDING);
29
+ }
30
+
31
+ /** A top-of-page bar while a page load is pending. */
32
+ export function LoadProgressBar({
33
+ pending = false,
34
+ className,
35
+ }: LoadProgressBarProps): JSX.Element | null {
36
+ const loading = useSyncExternalStore(subscribeToLoadProgress, isLoadInProgress, () => false);
37
+ const active = pending || loading;
38
+ const [progress, setProgress] = useState<number | null>(null);
39
+ const [fading, setFading] = useState(false);
40
+ const shown = useRef(false);
41
+
42
+ useEffect(() => {
43
+ if (active) {
44
+ shown.current = true;
45
+ setFading(false);
46
+ setProgress((current) => (current === null || current === 1 ? START : current));
47
+ const timer = setInterval(
48
+ () => setProgress((current) => trickle(current ?? START)),
49
+ TRICKLE_MS,
50
+ );
51
+ return () => clearInterval(timer);
52
+ }
53
+ if (!shown.current) return undefined;
54
+
55
+ setProgress(1);
56
+ const fade = setTimeout(() => setFading(true), SETTLE_MS);
57
+ const hide = setTimeout(() => {
58
+ shown.current = false;
59
+ setProgress(null);
60
+ setFading(false);
61
+ }, SETTLE_MS * 2);
62
+ return () => {
63
+ clearTimeout(fade);
64
+ clearTimeout(hide);
65
+ };
66
+ }, [active]);
67
+
68
+ if (progress === null) return null;
69
+
70
+ // The id and class names come from the replaced nprogress library: custom styles target them.
71
+ return (
72
+ <LoadProgressBarWrapper
73
+ id="nprogress"
74
+ data-component-name="LoadProgressBar/LoadProgressBar"
75
+ className={className}
76
+ aria-hidden="true"
77
+ $fading={fading}
78
+ >
79
+ <Bar className="bar" $progress={progress}>
80
+ <Peg className="peg" />
81
+ </Bar>
82
+ </LoadProgressBarWrapper>
83
+ );
84
+ }
85
+
86
+ const LoadProgressBarWrapper = styled.div<{ $fading: boolean }>`
87
+ pointer-events: none;
88
+ opacity: ${({ $fading }) => ($fading ? 0 : 1)};
89
+ transition: opacity ${SETTLE_MS}ms linear;
90
+ `;
91
+
92
+ // The offset changes on each tick: as a styled rule, each value would add a class.
93
+ const Bar = styled.div.attrs<{ $progress: number }>(({ $progress }) => ({
94
+ style: { transform: `translate3d(${($progress - 1) * 100}%, 0, 0)` },
95
+ }))`
96
+ position: fixed;
97
+ z-index: var(--z-index-popover);
98
+ top: 0;
99
+ left: 0;
100
+ width: 100%;
101
+ height: var(--load-progress-bar-height);
102
+ background: var(--load-progress-bar-color);
103
+ transition: transform ${SETTLE_MS}ms ease;
104
+ `;
105
+
106
+ const Peg = styled.div`
107
+ position: absolute;
108
+ right: 0;
109
+ width: 100px;
110
+ height: 100%;
111
+ box-shadow: var(--load-progress-bar-shadow);
112
+ transform: rotate(3deg) translate(0, -4px);
113
+ `;
@@ -10,9 +10,11 @@ import { useMCPConfig, useThemeHooks } from '@redocly/theme/core/hooks';
10
10
  import {
11
11
  generateClaudeCodeCommand,
12
12
  generateCodexCommand,
13
+ generateMCPDeepLink,
13
14
  generateMcpInstallPrompt,
14
15
  getBaseDataAttributes,
15
16
  } from '@redocly/theme/core/utils';
17
+ import { Button } from '@redocly/theme/components/Button/Button';
16
18
  import { CodeBlock } from '@redocly/theme/components/CodeBlock/CodeBlock';
17
19
  import { ClaudeIcon } from '@redocly/theme/icons/ClaudeIcon/ClaudeIcon';
18
20
  import { ChatGptIcon } from '@redocly/theme/icons/ChatGptIcon/ChatGptIcon';
@@ -167,16 +169,26 @@ function renderTabContent(
167
169
  ),
168
170
  },
169
171
  {
170
- headline: translate(
171
- 'page.mcpNotAllowed.snippets.claudeDesktop.headline',
172
- 'Claude Desktop',
173
- ),
172
+ headline: translate('page.mcpNotAllowed.snippets.claudeDesktop.headline', 'Claude app'),
174
173
  content: (
175
174
  <>
175
+ <TabHint>
176
+ {translate(
177
+ 'page.mcpNotAllowed.snippets.claudeDesktop.accountHint',
178
+ 'Claude adds the connector to your account and syncs it between Claude on the web and Claude Desktop.',
179
+ )}
180
+ </TabHint>
181
+ <ConnectButton
182
+ variant="secondary"
183
+ icon={<ClaudeIcon />}
184
+ onClick={() => window.open(generateMCPDeepLink('claude', connection), '_blank')}
185
+ >
186
+ {translate('page.actions.connectMcp.claude', 'Connect to Claude')}
187
+ </ConnectButton>
176
188
  <TabHint>
177
189
  {translate(
178
190
  'page.mcpNotAllowed.snippets.claudeDesktop.instruction',
179
- 'Open Customize → Connectors → Add custom connector and paste this server URL:',
191
+ 'Or open Customize → Connectors → Add custom connector and paste this server URL:',
180
192
  )}
181
193
  </TabHint>
182
194
  <CodeBlock
@@ -278,6 +290,11 @@ const McpConnectionTabsWrapper = styled.div`
278
290
  }
279
291
  `;
280
292
 
293
+ const ConnectButton = styled(Button)`
294
+ align-self: flex-start;
295
+ margin-bottom: var(--spacing-sm);
296
+ `;
297
+
281
298
  const TabHint = styled.p`
282
299
  margin: 0 0 var(--spacing-xs);
283
300
  color: var(--page-mcp-405-snippets-hint-text-color);
@@ -71,7 +71,7 @@ export const Markdown = styled.main
71
71
  ${markdownLinksCss}
72
72
 
73
73
  a[name], [id] {
74
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
74
+ scroll-margin-top: var(--navbar-offset);
75
75
  }
76
76
 
77
77
  img,
@@ -84,7 +84,7 @@ export const Markdown = styled.main
84
84
  font-family: var(--heading-font-family);
85
85
  position: relative;
86
86
 
87
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
87
+ scroll-margin-top: var(--navbar-offset);
88
88
  ${headingAnchorCss(ANCHOR_CLASS)};
89
89
 
90
90
  h1,
@@ -295,6 +295,7 @@ export const Markdown = styled.main
295
295
  font-size: inherit;
296
296
  font-family: inherit;
297
297
  border: none;
298
+ padding: 0;
298
299
  }
299
300
  }
300
301
 
@@ -22,7 +22,7 @@ export const markdownBaseTableCss = css`
22
22
  color: var(--md-table-cell-text-color);
23
23
  font-size: var(--md-table-font-size);
24
24
  line-height: var(--md-table-line-height);
25
- vertical-align: top;
25
+ vertical-align: var(--md-table-cell-vertical-align);
26
26
  }
27
27
 
28
28
  thead td,
@@ -71,5 +71,18 @@ export const markdownBaseTableCss = css`
71
71
  th[align='right'] {
72
72
  text-align: right;
73
73
  }
74
+
75
+ th[valign='top'],
76
+ td[valign='top'] {
77
+ vertical-align: top;
78
+ }
79
+ th[valign='middle'],
80
+ td[valign='middle'] {
81
+ vertical-align: middle;
82
+ }
83
+ th[valign='bottom'],
84
+ td[valign='bottom'] {
85
+ vertical-align: bottom;
86
+ }
74
87
  }
75
88
  `;
@@ -51,6 +51,7 @@ export const markdown = css`
51
51
  --md-table-cell-text-color: var(--text-color-secondary); // @presenter Color
52
52
  --md-table-cell-padding: var(--spacing-xs) var(--spacing-sm); // @presenter Spacing
53
53
  --md-table-footer-cell-padding: var(--spacing-xxs) var(--spacing-sm); // @presenter Spacing
54
+ --md-table-cell-vertical-align: top;
54
55
 
55
56
  --md-table-head-bg-color: var(--md-table-bg-color); // @presenter Color
56
57
  --md-table-head-text-color: var(--text-color-primary); // @presenter Color
@@ -5,6 +5,7 @@ import type { JSX } from 'react';
5
5
  import type { DrilldownMenuItemDetails, ItemState } from '@redocly/theme/core/types';
6
6
 
7
7
  import { MenuItem } from '@redocly/theme/components/Menu/MenuItem';
8
+ import { MenuSelect } from '@redocly/theme/components/Menu/MenuSelect';
8
9
  import { MenuItemType } from '@redocly/theme/core/constants';
9
10
  import { getMenuItemType } from '@redocly/theme/core/utils';
10
11
 
@@ -28,6 +29,10 @@ export function Menu({
28
29
  return (
29
30
  <MenuWrapper className={className} data-component-name="Menu/Menu">
30
31
  {items.map((item, index) => {
32
+ if (getMenuItemType(item) === MenuItemType.Select) {
33
+ return <MenuSelect item={item} key={`${item.label}-${index}`} />;
34
+ }
35
+
31
36
  return (
32
37
  <MenuItem
33
38
  item={item}
@@ -0,0 +1,198 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { JSX } from 'react';
5
+ import type { ItemState } from '@redocly/theme/core/types';
6
+
7
+ import { getBaseDataAttributes } from '@redocly/theme/core/utils';
8
+ import { useThemeHooks } from '@redocly/theme/core/hooks';
9
+ import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
10
+ import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
11
+ import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
12
+ import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
13
+ import { LaunchIcon } from '@redocly/theme/icons/LaunchIcon/LaunchIcon';
14
+ import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
15
+ import { CheckmarkIcon } from '@redocly/theme/icons/CheckmarkIcon/CheckmarkIcon';
16
+
17
+ export type MenuSelectProps = {
18
+ item: ItemState;
19
+ className?: string;
20
+ };
21
+
22
+ export function MenuSelect({ item, className }: MenuSelectProps): JSX.Element {
23
+ const { useTranslate, useTelemetry } = useThemeHooks();
24
+ const { translate } = useTranslate();
25
+ const telemetry = useTelemetry();
26
+
27
+ return (
28
+ <MenuSelectWrapper data-component-name="Menu/MenuSelect" className={className} role="listitem">
29
+ <MenuSelectDropdown
30
+ alignment="start"
31
+ trigger={
32
+ <MenuSelectTrigger type="button">
33
+ <MenuSelectLabel>{translate(item.labelTranslationKey, item.label)}</MenuSelectLabel>
34
+ <MenuSelectChevron
35
+ size="var(--menu-select-icon-size)"
36
+ color="--menu-select-icon-color"
37
+ />
38
+ </MenuSelectTrigger>
39
+ }
40
+ >
41
+ <MenuSelectMenu>
42
+ {item.items.map((option, index) => {
43
+ const key = `${option.link || option.label}-${index}`;
44
+ const checkmark = option.active ? (
45
+ <MenuSelectCheckmark size="var(--menu-select-option-checkmark-size)" />
46
+ ) : null;
47
+ const content = (
48
+ <MenuSelectOptionContent $active={option.active}>
49
+ {option.icon || option.srcSet ? (
50
+ <MenuSelectOptionIcon icon={option.icon} srcSet={option.srcSet} />
51
+ ) : null}
52
+ {translate(option.labelTranslationKey, option.label)}
53
+ {option.external ? (
54
+ <LaunchIcon size="var(--menu-select-option-external-icon-size)" />
55
+ ) : null}
56
+ </MenuSelectOptionContent>
57
+ );
58
+
59
+ if (!option.link) {
60
+ return (
61
+ <MenuSelectOption
62
+ key={key}
63
+ active={option.active}
64
+ prefix={checkmark}
65
+ dataAttributes={{ 'aria-disabled': 'true' }}
66
+ >
67
+ {content}
68
+ </MenuSelectOption>
69
+ );
70
+ }
71
+
72
+ return (
73
+ <MenuSelectOption
74
+ key={key}
75
+ to={option.link}
76
+ external={option.external}
77
+ target={option.target === '_blank' ? '_blank' : undefined}
78
+ active={option.active}
79
+ aria-current={option.active ? 'page' : undefined}
80
+ prefix={checkmark}
81
+ onAction={() =>
82
+ telemetry.sendSidebarItemClickedMessage([
83
+ {
84
+ ...getBaseDataAttributes('sidebarItem', 'sidebar'),
85
+ label: option.label,
86
+ type: 'link',
87
+ },
88
+ ])
89
+ }
90
+ >
91
+ {content}
92
+ </MenuSelectOption>
93
+ );
94
+ })}
95
+ </MenuSelectMenu>
96
+ </MenuSelectDropdown>
97
+ </MenuSelectWrapper>
98
+ );
99
+ }
100
+
101
+ const MenuSelectWrapper = styled.div`
102
+ margin: var(--menu-select-margin);
103
+ `;
104
+
105
+ const MenuSelectDropdown = styled(Dropdown)`
106
+ --dropdown-menu-padding-top: var(--menu-select-menu-offset);
107
+ --dropdown-menu-padding: var(--menu-select-menu-padding);
108
+ --dropdown-menu-border-radius: var(--menu-select-menu-border-radius);
109
+ --dropdown-menu-item-gap: var(--menu-select-option-gap);
110
+ --dropdown-menu-item-border-radius: var(--menu-select-option-border-radius);
111
+ --dropdown-menu-item-bg-color-active: var(--menu-select-option-bg-color-active);
112
+ --dropdown-menu-item-color-active: var(--menu-select-option-text-color-active);
113
+
114
+ width: 100%;
115
+
116
+ > * {
117
+ min-width: 100%;
118
+ }
119
+ `;
120
+
121
+ const MenuSelectChevron = styled(ChevronDownIcon)`
122
+ transition: var(--menu-select-transition);
123
+ `;
124
+
125
+ const MenuSelectTrigger = styled.button`
126
+ display: flex;
127
+ align-items: center;
128
+ gap: var(--menu-select-gap);
129
+ box-sizing: border-box;
130
+ width: 100%;
131
+ height: var(--menu-select-height);
132
+ padding: 0 var(--menu-select-padding-horizontal);
133
+ border: var(--menu-select-border);
134
+ border-radius: var(--menu-select-border-radius);
135
+ background-color: var(--menu-select-bg-color);
136
+ color: var(--menu-select-text-color);
137
+ font-family: inherit;
138
+ font-size: var(--menu-select-font-size);
139
+ line-height: var(--menu-select-line-height);
140
+ text-align: left;
141
+ cursor: pointer;
142
+
143
+ &:focus-visible {
144
+ outline: 1px solid var(--menu-select-border-color-focused);
145
+ }
146
+
147
+ &[aria-expanded='true'] ${MenuSelectChevron} {
148
+ transform: rotate(180deg);
149
+ }
150
+ `;
151
+
152
+ const MenuSelectLabel = styled.span`
153
+ flex: 1;
154
+ min-width: 0;
155
+ overflow: hidden;
156
+ text-overflow: ellipsis;
157
+ white-space: nowrap;
158
+ `;
159
+
160
+ const MenuSelectMenu = styled(DropdownMenu)`
161
+ box-sizing: border-box;
162
+ width: 100%;
163
+ max-width: 100%;
164
+ `;
165
+
166
+ const MenuSelectOption = styled(DropdownMenuItem)`
167
+ position: relative;
168
+ box-sizing: border-box;
169
+ padding: var(--menu-select-option-padding);
170
+
171
+ &[aria-disabled='true'] {
172
+ cursor: default;
173
+ pointer-events: none;
174
+ }
175
+ `;
176
+
177
+ const MenuSelectCheckmark = styled(CheckmarkIcon)`
178
+ position: absolute;
179
+ top: 50%;
180
+ left: var(--menu-select-option-checkmark-offset);
181
+ transform: translateY(-50%);
182
+ `;
183
+
184
+ const MenuSelectOptionContent = styled.span<{ $active: boolean }>`
185
+ display: inline-flex;
186
+ align-items: center;
187
+ gap: var(--menu-select-option-content-gap);
188
+ font-weight: ${({ $active }) =>
189
+ $active
190
+ ? 'var(--menu-select-option-font-weight-active)'
191
+ : 'var(--menu-select-option-font-weight)'};
192
+ `;
193
+
194
+ const MenuSelectOptionIcon = styled(GenericIcon)`
195
+ --icon-width: var(--menu-select-option-icon-size);
196
+ --icon-height: var(--menu-select-option-icon-size);
197
+ flex-shrink: 0;
198
+ `;
@@ -102,6 +102,45 @@ export const menu = css`
102
102
  --menu-back-button-gap: var(--spacing-xs);
103
103
  --menu-back-button-icon: none;
104
104
 
105
+ /**
106
+ * @tokens Menu select
107
+ */
108
+ --menu-select-margin-top: 0;
109
+ --menu-select-margin-bottom: var(--spacing-xs);
110
+ --menu-select-margin-horizontal: var(--menu-item-label-margin-horizontal);
111
+ --menu-select-margin: var(--menu-select-margin-top) var(--menu-select-margin-horizontal) var(--menu-select-margin-bottom); // @presenter Spacing
112
+ --menu-select-height: 32px; // @presenter Spacing
113
+ --menu-select-padding-horizontal: calc(var(--spacing-sm) - var(--border-width)); // @presenter Spacing
114
+ --menu-select-gap: var(--spacing-xxs); // @presenter Spacing
115
+ --menu-select-font-size: var(--font-size-base); // @presenter FontSize
116
+ --menu-select-line-height: var(--line-height-base); // @presenter LineHeight
117
+ --menu-select-text-color: var(--input-content-color-active); // @presenter Color
118
+ --menu-select-bg-color: var(--input-bg-color); // @presenter Color
119
+ --menu-select-border: var(--input-border); // @presenter Border
120
+ --menu-select-border-color-focused: var(--input-border-color-focused); // @presenter Color
121
+ --menu-select-border-radius: var(--input-border-radius); // @presenter BorderRadius
122
+ --menu-select-icon-size: 16px;
123
+ --menu-select-icon-color: var(--icon-color-secondary); // @presenter Color
124
+ --menu-select-transition: transform 150ms ease-in-out;
125
+ --menu-select-menu-offset: var(--spacing-xs); // @presenter Spacing
126
+ --menu-select-menu-padding: calc(var(--dropdown-menu-padding) - var(--border-width)); // @presenter Spacing
127
+ --menu-select-menu-border-radius: var(--border-radius-lg); // @presenter BorderRadius
128
+ --menu-select-option-gap: calc(var(--spacing-unit) / 2); // @presenter Spacing
129
+ --menu-select-option-content-gap: var(--spacing-xs); // @presenter Spacing
130
+ --menu-select-option-padding-vertical: var(--dropdown-menu-item-padding-vertical);
131
+ --menu-select-option-padding-left: var(--spacing-md);
132
+ --menu-select-option-padding-right: var(--spacing-sm);
133
+ --menu-select-option-padding: var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-right) var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-left); // @presenter Spacing
134
+ --menu-select-option-border-radius: var(--border-radius-md); // @presenter BorderRadius
135
+ --menu-select-option-font-weight: var(--font-weight-regular); // @presenter FontWeight
136
+ --menu-select-option-font-weight-active: var(--font-weight-medium); // @presenter FontWeight
137
+ --menu-select-option-text-color-active: var(--text-color-primary); // @presenter Color
138
+ --menu-select-option-bg-color-active: transparent; // @presenter Color
139
+ --menu-select-option-icon-size: var(--menu-item-icon-size);
140
+ --menu-select-option-external-icon-size: var(--menu-item-external-icon-size);
141
+ --menu-select-option-checkmark-size: 14px;
142
+ --menu-select-option-checkmark-offset: calc((var(--menu-select-option-padding-left) - var(--menu-select-option-checkmark-size)) / 2);
143
+
105
144
  /**
106
145
  * @tokens Menu items
107
146
  */
@@ -133,18 +172,18 @@ export const mobileMenu = css`
133
172
  * @tokens Mobile Menu
134
173
  * */
135
174
  /* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
136
- --menu-mobile-height: calc(100vh - var(--navbar-height) - var(--banner-height));
137
- --menu-mobile-height: calc(100dvh - var(--navbar-height) - var(--banner-height));
175
+ --menu-mobile-height: calc(100vh - var(--navbar-offset));
176
+ --menu-mobile-height: calc(100dvh - var(--navbar-offset));
138
177
  --menu-mobile-width: 100%;
139
178
  --menu-mobile-z-index: var(--z-index-raised);
140
179
  --menu-mobile-left: 0;
141
- --menu-mobile-top: calc(var(--navbar-height) + var(--banner-height));
180
+ --menu-mobile-top: var(--navbar-offset);
142
181
  --menu-mobile-transition: 0.5s;
143
182
  --menu-mobile-bg: var(--bg-color); // @presenter Color
144
183
  --menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
145
184
  --menu-mobile-line-height: var(--line-height-base); // @presenter LineHeight
146
185
  --menu-mobile-padding-top: var(--spacing-sm); // @presenter Spacing
147
- --menu-mobile-margin-horizontal: var(--spacing-xs); // @presenter Spacing
186
+ --menu-mobile-margin-horizontal: 0; // @presenter Spacing
148
187
  --menu-mobile-items-margin-top: var(--spacing-xxs); // @presenter Spacing
149
188
 
150
189
  --menu-mobile-profile-bg-color: var(--bg-color); // @presenter Color
@@ -1,13 +1,18 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
5
5
  import type { ResolvedConfigLinks } from '@redocly/config';
6
6
 
7
- import { breakpoints, getBaseDataAttributes } from '@redocly/theme/core/utils';
7
+ import {
8
+ breakpoints,
9
+ getBaseDataAttributes,
10
+ toNavigationTabsConfig,
11
+ } from '@redocly/theme/core/utils';
8
12
  import { useThemeHooks, useThemeConfig, useMobileMenu } from '@redocly/theme/core/hooks';
9
13
  import { NavbarLogo } from '@redocly/theme/components/Navbar/NavbarLogo';
10
14
  import { NavbarMenu } from '@redocly/theme/components/Navbar/NavbarMenu';
15
+ import { NavigationTabs } from '@redocly/theme/components/NavigationTabs/NavigationTabs';
11
16
  import { MenuMobile } from '@redocly/theme/components/Menu/MenuMobile';
12
17
  import { ColorModeSwitcher } from '@redocly/theme/components/ColorModeSwitcher/ColorModeSwitcher';
13
18
  import { Search } from '@redocly/theme/components/Search/Search';
@@ -26,9 +31,15 @@ export type NavbarProps = {
26
31
  export function Navbar({ className }: NavbarProps): JSX.Element | null {
27
32
  const { isOpen, closeMobileMenu, openMobileMenu } = useMobileMenu(false);
28
33
  const themeConfig = useThemeConfig();
29
- const { useL10n, useTelemetry } = useThemeHooks();
34
+ const { useL10n, useTelemetry, useTranslate, useNavigationTabs } = useThemeHooks();
30
35
  const { changeLanguage } = useL10n();
36
+ const { translate } = useTranslate();
31
37
  const telemetry = useTelemetry();
38
+ const navigationTabs = useNavigationTabs();
39
+ const navigationTabsConfig = useMemo(
40
+ () => toNavigationTabsConfig({ state: navigationTabs }),
41
+ [navigationTabs],
42
+ );
32
43
 
33
44
  const menu = themeConfig.navbar?.items;
34
45
 
@@ -43,7 +54,11 @@ export function Navbar({ className }: NavbarProps): JSX.Element | null {
43
54
  const hideUserMenu = userMenuSettings?.hide;
44
55
 
45
56
  return (
46
- <NavbarWrapper data-component-name="Navbar/Navbar" className={className}>
57
+ <NavbarWrapper
58
+ data-component-name="Navbar/Navbar"
59
+ className={className}
60
+ aria-label={translate('navbar.label', 'Main navigation')}
61
+ >
47
62
  <Banner />
48
63
  {isOpen && <MenuMobile hideUserProfile={!!hideUserMenu} />}
49
64
  <NavbarRow>
@@ -76,13 +91,14 @@ export function Navbar({ className }: NavbarProps): JSX.Element | null {
76
91
  />
77
92
  {hideUserMenu ? null : <UserMenu />}
78
93
  </NavbarRow>
94
+ {navigationTabsConfig && <NavigationTabs config={navigationTabsConfig} />}
79
95
  </NavbarWrapper>
80
96
  );
81
97
  }
82
98
 
83
99
  const NavbarWrapper = styled.nav`
84
100
  --text-color: var(--navbar-text-color);
85
- height: calc(var(--navbar-height) + var(--banner-height));
101
+ height: var(--navbar-offset, calc(var(--navbar-height) + var(--banner-height)));
86
102
  transition: height 0.4s ease-out;
87
103
 
88
104
  position: sticky;
@@ -123,6 +139,7 @@ const NavbarRow = styled.div`
123
139
  box-sizing: border-box;
124
140
  margin-top: var(--banner-height);
125
141
  transition: margin-top 0.5s ease-out;
142
+ border-bottom-color: var(--navbar-row-bottom-border-color, var(--navbar-border-color));
126
143
 
127
144
  @media screen and (min-width: ${breakpoints.max}) {
128
145
  max-width: var(--container-max-width);