@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
@@ -6,9 +6,9 @@ import {
6
6
  type SearchAiMessageResource,
7
7
  type ToolCall,
8
8
  type ContentSegment,
9
- ToolCallName,
10
9
  } from '@redocly/theme/core/types';
11
- import { TOOL_CALL_DISPLAY_TEXT, AiSearchConversationRole } from '@redocly/theme/core/constants';
10
+ import { AiSearchConversationRole } from '@redocly/theme/core/constants';
11
+ import { groupToolCallSegments, hasToolCallsAndText } from '@redocly/theme/core/utils';
12
12
  import { Link } from '@redocly/theme/components/Link/Link';
13
13
  import { Tag } from '@redocly/theme/components/Tag/Tag';
14
14
  import { useThemeHooks } from '@redocly/theme/core/hooks';
@@ -18,43 +18,14 @@ import { AiStarsIcon } from '@redocly/theme/icons/AiStarsIcon/AiStarsIcon';
18
18
  import { CheckmarkOutlineIcon } from '@redocly/theme/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon';
19
19
  import { SearchAiActionButtons } from '@redocly/theme/components/Search/SearchAiActionButtons';
20
20
  import { SearchAiNegativeFeedbackForm } from '@redocly/theme/components/Search/SearchAiNegativeFeedbackForm';
21
+ import { SearchAiActivity } from '@redocly/theme/components/Search/SearchAiActivity';
22
+ import { searchAiAppearAnimation } from '@redocly/theme/core/styles';
21
23
 
22
24
  function MarkdownSegment({ text }: { text: string }): JSX.Element {
23
25
  const { useMarkdownText } = useThemeHooks();
24
26
  const markdown = useMarkdownText(text);
25
27
  return <ResponseText as="div" children={markdown} data-testid="response-text" />;
26
28
  }
27
- // The codemode `execute` tool passes a human-readable `description` of what its code
28
- // does; show that instead of a generic "Executing execute..." label.
29
- function getExecuteDescription(args: unknown): string | undefined {
30
- if (args && typeof args === 'object' && 'description' in args) {
31
- const { description } = args as { description?: unknown };
32
- if (typeof description === 'string' && description.trim().length > 0) {
33
- return description.trim();
34
- }
35
- }
36
- return undefined;
37
- }
38
-
39
- function getToolCallDisplayText(toolCall: ToolCall): {
40
- inProgressText: string;
41
- completedText: string;
42
- } {
43
- if (toolCall.name === ToolCallName.Execute) {
44
- const description = getExecuteDescription(toolCall.args);
45
- if (description) {
46
- return { inProgressText: description, completedText: description };
47
- }
48
- }
49
-
50
- return (
51
- TOOL_CALL_DISPLAY_TEXT[toolCall.name] ?? {
52
- inProgressText: `Executing ${toolCall.name}...`,
53
- completedText: `${toolCall.name} executed`,
54
- }
55
- );
56
- }
57
-
58
29
  export type SearchAiMessageProps = {
59
30
  role: AiSearchConversationRole;
60
31
  content: string;
@@ -64,6 +35,7 @@ export type SearchAiMessageProps = {
64
35
  messageId?: string;
65
36
  feedback?: FeedbackType;
66
37
  onFeedbackChange: (messageId: string, feedback: FeedbackType | undefined) => void;
38
+ /** @deprecated Not used; the message reads its tool calls from `contentSegments`. */
67
39
  toolCalls?: ToolCall[];
68
40
  contentSegments?: ContentSegment[];
69
41
  };
@@ -77,7 +49,6 @@ function SearchAiMessageComponent({
77
49
  messageId,
78
50
  feedback,
79
51
  onFeedbackChange,
80
- toolCalls = [],
81
52
  contentSegments = [{ type: 'text' as const, text: content }],
82
53
  }: SearchAiMessageProps): JSX.Element {
83
54
  const { useTranslate, useTelemetry } = useThemeHooks();
@@ -90,7 +61,8 @@ function SearchAiMessageComponent({
90
61
 
91
62
  const showSuccessMessage = feedbackSent && feedback;
92
63
 
93
- const isLoading = isThinking && content.length === 0 && toolCalls.length === 0;
64
+ const groupedSegments = groupToolCallSegments(contentSegments, isThinking);
65
+ const isFullWidth = hasToolCallsAndText(contentSegments);
94
66
 
95
67
  const sendFeedbackTelemetry = (feedbackValue: FeedbackType, dislikeReason?: string) => {
96
68
  if (!messageId) return;
@@ -143,29 +115,18 @@ function SearchAiMessageComponent({
143
115
  margin="0 var(--spacing-xs) 0 0"
144
116
  />
145
117
  )}
146
- <MessageContentWrapper>
118
+ <MessageContentWrapper $isFullWidth={isFullWidth}>
147
119
  {role === AiSearchConversationRole.ASSISTANT ? (
148
120
  <>
149
- <MessageWrapper $role={role}>
150
- {contentSegments.map((segment, index) => {
151
- if (segment.type === 'tool') {
152
- const toolCallCompleted = Boolean(segment.toolCall.result);
153
-
154
- const { inProgressText, completedText } = getToolCallDisplayText(
155
- segment.toolCall,
156
- );
157
-
158
- const toolCallDisplayText = toolCallCompleted ? completedText : inProgressText;
159
-
121
+ <MessageWrapper $role={role} $isFullWidth={isFullWidth}>
122
+ {groupedSegments.map((segment, index) => {
123
+ if (segment.type === 'tools') {
160
124
  return (
161
- <ToolCallsInfoWrapper key={`tool-${index}`} data-testid="tool-calls-info">
162
- <ToolCallInfoItem>
163
- <DocumentIcon size="14px" color="--search-ai-text-color" />
164
- <ToolCallText $isSearching={!toolCallCompleted}>
165
- {toolCallDisplayText}
166
- </ToolCallText>
167
- </ToolCallInfoItem>
168
- </ToolCallsInfoWrapper>
125
+ <ToolCallsActivity
126
+ key={`tools-${index}`}
127
+ toolCalls={segment.toolCalls}
128
+ isActive={segment.isActive}
129
+ />
169
130
  );
170
131
  }
171
132
 
@@ -193,14 +154,7 @@ function SearchAiMessageComponent({
193
154
  </ResourcesWrapper>
194
155
  </>
195
156
  )}
196
- {isLoading && (
197
- <ThinkingDotsWrapper data-testid="thinking-dots-wrapper">
198
- <ThinkingDot />
199
- <ThinkingDot />
200
- <ThinkingDot />
201
- </ThinkingDotsWrapper>
202
- )}
203
- {content.length > 0 && (
157
+ {!isThinking && content.length > 0 && (
204
158
  <FeedbackWrapper>
205
159
  <SearchAiActionButtons
206
160
  content={content}
@@ -261,7 +215,6 @@ export const SearchAiMessage = memo(SearchAiMessageComponent, (prevProps, nextPr
261
215
  prevProps.feedback === nextProps.feedback &&
262
216
  prevProps.onFeedbackChange === nextProps.onFeedbackChange &&
263
217
  areResourcesEqual(prevProps.resources, nextProps.resources) &&
264
- prevProps.toolCalls?.length === nextProps.toolCalls?.length &&
265
218
  prevProps.contentSegments === nextProps.contentSegments
266
219
  );
267
220
  });
@@ -275,9 +228,10 @@ const SearchAiMessageWrapper = styled.div<{ $role: string }>`
275
228
  $role === AiSearchConversationRole.USER ? 'flex-end' : 'flex-start'};
276
229
  `;
277
230
 
278
- const MessageContentWrapper = styled.div`
231
+ const MessageContentWrapper = styled.div<{ $isFullWidth: boolean }>`
279
232
  display: flex;
280
233
  flex-direction: column;
234
+ flex-grow: ${({ $isFullWidth }) => ($isFullWidth ? 1 : 0)};
281
235
  gap: var(--spacing-sm);
282
236
  max-width: 80%;
283
237
  min-width: 0;
@@ -300,13 +254,13 @@ const ResponseText = styled(Markdown)`
300
254
  }
301
255
  `;
302
256
 
303
- const MessageWrapper = styled.div<{ $role: string }>`
257
+ const MessageWrapper = styled.div<{ $role: string; $isFullWidth?: boolean }>`
304
258
  padding: ${({ $role }) =>
305
259
  $role === AiSearchConversationRole.USER
306
260
  ? 'var(--spacing-sm)'
307
261
  : 'var(--spacing-sm) var(--spacing-sm) var(--spacing-xs) var(--spacing-sm)'};
308
262
  border-radius: var(--border-radius-xl);
309
- width: fit-content;
263
+ width: ${({ $isFullWidth }) => ($isFullWidth ? 'auto' : 'fit-content')};
310
264
  max-width: 100%;
311
265
  word-wrap: break-word;
312
266
  white-space: pre-wrap;
@@ -327,12 +281,14 @@ const ResourcesWrapper = styled.div`
327
281
  display: flex;
328
282
  flex-direction: column;
329
283
  margin: 0;
284
+ ${searchAiAppearAnimation}
330
285
  `;
331
286
  const FeedbackWrapper = styled.div`
332
287
  display: flex;
333
288
  flex-direction: row;
334
289
  gap: var(--search-ai-feedback-gap);
335
290
  margin-top: var(--spacing-sm);
291
+ ${searchAiAppearAnimation}
336
292
  `;
337
293
 
338
294
  const ResourcesTitle = styled.div`
@@ -347,7 +303,7 @@ const ResourceTagsWrapper = styled.div`
347
303
  gap: var(--search-ai-resource-tags-gap);
348
304
  `;
349
305
 
350
- const ResourceTag = styled(Tag)`
306
+ const ResourceTag = styled(Tag).attrs({ textTransform: 'none' })`
351
307
  .tag-default {
352
308
  --tag-color: var(--search-ai-resource-tag-text-color);
353
309
  max-width: 100%;
@@ -367,43 +323,6 @@ const ResourceTag = styled(Tag)`
367
323
  }
368
324
  `;
369
325
 
370
- const ThinkingDotsWrapper = styled.div`
371
- display: flex;
372
- gap: var(--search-ai-thinking-dots-gap);
373
- padding: var(--search-ai-thinking-dots-padding);
374
- `;
375
-
376
- const ThinkingDot = styled.div`
377
- width: var(--search-ai-thinking-dot-size);
378
- height: var(--search-ai-thinking-dot-size);
379
- border-radius: 50%;
380
- background: var(--search-ai-thinking-dot-color);
381
- animation: bounce 1.4s infinite ease-in-out;
382
-
383
- &:nth-child(1) {
384
- animation-delay: -0.32s;
385
- }
386
- &:nth-child(2) {
387
- animation-delay: -0.16s;
388
- }
389
- &:nth-child(3) {
390
- animation-delay: 0s;
391
- }
392
-
393
- @keyframes bounce {
394
- 0%,
395
- 80%,
396
- 100% {
397
- opacity: 0.2;
398
- transform: scale(0.8);
399
- }
400
- 40% {
401
- opacity: 1;
402
- transform: scale(1);
403
- }
404
- }
405
- `;
406
-
407
326
  const SuccessMessageWrapper = styled.div`
408
327
  max-width: fit-content;
409
328
  display: flex;
@@ -420,37 +339,10 @@ const SuccessMessageText = styled.div`
420
339
  color: var(--color-success-darker);
421
340
  `;
422
341
 
423
- const ToolCallsInfoWrapper = styled.div`
424
- display: flex;
425
- flex-direction: column;
426
- gap: var(--spacing-xxs);
342
+ const ToolCallsActivity = styled(SearchAiActivity)`
427
343
  margin: 0 0 var(--spacing-sm) 0;
428
- font-size: var(--font-size-xs);
429
- color: var(--search-ai-text-color);
430
- opacity: 0.6;
431
- `;
432
-
433
- const ToolCallInfoItem = styled.div`
434
- display: flex;
435
- align-items: center;
436
- gap: var(--spacing-xxs);
437
- `;
438
-
439
- const ToolCallText = styled.span<{ $isSearching?: boolean }>`
440
- font-weight: var(--font-weight-regular);
441
344
 
442
- ${({ $isSearching }) =>
443
- $isSearching &&
444
- `
445
- animation: pulse 1.5s ease-in-out infinite;
446
-
447
- @keyframes pulse {
448
- 0%, 100% {
449
- opacity: 1;
450
- }
451
- 50% {
452
- opacity: 0.4;
453
- }
454
- }
455
- `}
345
+ &:last-child {
346
+ margin-bottom: var(--spacing-xxs);
347
+ }
456
348
  `;
@@ -212,6 +212,7 @@ const ResourceTags = styled.div`
212
212
 
213
213
  const ResourceTag = styled(Tag).attrs({
214
214
  className: 'tag-resource',
215
+ textTransform: 'none',
215
216
  })`
216
217
  .tag-default {
217
218
  --tag-color: --search-ai-resource-tag-text-color;
@@ -19,6 +19,7 @@ import {
19
19
  useSearchFilter,
20
20
  useRecentSearches,
21
21
  useModalScrollLock,
22
+ usePersistedQuickFilter,
22
23
  } from '@redocly/theme/core/hooks';
23
24
  import { Tag } from '@redocly/theme/components/Tag/Tag';
24
25
  import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
@@ -81,6 +82,16 @@ export function SearchDialog({
81
82
  onFacetReset,
82
83
  onQuickFilterReset,
83
84
  } = useSearchFilter(filter, setFilter);
85
+ usePersistedQuickFilter({
86
+ filter,
87
+ setFilter,
88
+ facets,
89
+ groupField,
90
+ query,
91
+ isSearchLoading,
92
+ searchError,
93
+ enabled: initialMode === 'search',
94
+ });
84
95
  const { addSearchHistoryItem } = useRecentSearches();
85
96
  const aiSearch = useAiSearch({ filter: filter, product: product?.name });
86
97
  useModalScrollLock(true);
@@ -9,7 +9,7 @@ import { Link } from '@redocly/theme/components/Link/Link';
9
9
  import { Image } from '@redocly/theme/components/Image/Image';
10
10
  import { searchHighlight } from '@redocly/theme/components/Search/SearchHighlight';
11
11
  import { Badge } from '@redocly/theme/components/Badge/Badge';
12
- import { trimText, getOperationColor } from '@redocly/theme/core/utils';
12
+ import { assignRef, trimText, getOperationColor } from '@redocly/theme/core/utils';
13
13
  import { ReturnKeyIcon } from '@redocly/theme/icons/ReturnKeyIcon/ReturnKeyIcon';
14
14
  import { useThemeHooks } from '@redocly/theme/core/hooks';
15
15
 
@@ -61,14 +61,7 @@ export function SearchItem({
61
61
  tabIndex={0}
62
62
  innerRef={(el: HTMLAnchorElement) => {
63
63
  ref.current = el;
64
-
65
- if (!innerRef) return;
66
-
67
- if (typeof innerRef === 'function') {
68
- innerRef(el);
69
- } else {
70
- innerRef.current = el;
71
- }
64
+ assignRef(innerRef, el);
72
65
  }}
73
66
  data-component-name="Search/SearchItem"
74
67
  >
@@ -85,7 +78,9 @@ export function SearchItem({
85
78
  <SearchItemOperationTag color={httpColor}>
86
79
  {document.httpMethod.toUpperCase()}
87
80
  </SearchItemOperationTag>
88
- {highlight.httpPath ? searchHighlight(highlight.httpPath) : document.httpPath}
81
+ <span>
82
+ {highlight.httpPath ? searchHighlight(highlight.httpPath) : document.httpPath}
83
+ </span>
89
84
  </SearchItemOperation>
90
85
  ) : null}
91
86
  <SearchItemTitleWrapper>
@@ -123,6 +118,20 @@ export function SearchItem({
123
118
  {searchHighlight(parameter.name)}
124
119
  </div>
125
120
  <div>{searchHighlight(parameter.description)}</div>
121
+ {parameter.enum ? (
122
+ <div>
123
+ {translate('search.searchItem.enum', 'Enum')}
124
+ {': '}
125
+ {searchHighlight(parameter.enum)}
126
+ </div>
127
+ ) : null}
128
+ {parameter.example ? (
129
+ <div>
130
+ {translate('search.searchItem.example', 'Example')}
131
+ {': '}
132
+ {searchHighlight(parameter.example)}
133
+ </div>
134
+ ) : null}
126
135
  </SearchItemPlace>
127
136
  ) : (
128
137
  shouldShowPath && (
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import styled from 'styled-components';
2
+ import styled, { keyframes } from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
5
5
 
@@ -9,6 +9,9 @@ import { SearchIcon } from '@redocly/theme/icons/SearchIcon/SearchIcon';
9
9
  import { breakpoints, getUserAgent } from '@redocly/theme/core/utils';
10
10
  import { DEFAULT_KEYBOARD_SHORTCUTS } from '@redocly/theme/core/constants';
11
11
 
12
+ const MAC_SHORTCUT_LABEL = '⌘K';
13
+ const SHORTCUT_LABEL = 'Ctrl+K';
14
+
12
15
  export type SearchTriggerProps = {
13
16
  onClick: () => void;
14
17
  className?: string;
@@ -31,7 +34,10 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
31
34
  }
32
35
 
33
36
  mainShortcutKey = mainShortcutKey?.toUpperCase();
34
- const isMac = getUserAgent().includes('Mac');
37
+ // A page can be cached and served to every platform, so the server renders an empty
38
+ // slot and the browser picks the label after hydration.
39
+ const [isMac, setIsMac] = React.useState<boolean | undefined>(undefined);
40
+ React.useEffect(() => setIsMac(getUserAgent().includes('Mac')), []);
35
41
 
36
42
  return (
37
43
  <SearchTriggerWrapper
@@ -53,7 +59,13 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
53
59
  <SearchIcon />
54
60
  {translate('search.navbar.label', 'Search')}
55
61
  {mainShortcutKey === DEFAULT_KEYBOARD_SHORTCUTS ? (
56
- <span>{isMac ? '⌘K' : 'Ctrl+K'}</span>
62
+ <SearchTriggerShortcut>
63
+ {isMac === undefined ? null : (
64
+ <SearchTriggerShortcutLabel>
65
+ {isMac ? MAC_SHORTCUT_LABEL : SHORTCUT_LABEL}
66
+ </SearchTriggerShortcutLabel>
67
+ )}
68
+ </SearchTriggerShortcut>
57
69
  ) : (
58
70
  <span>{mainShortcutKey}</span>
59
71
  )}
@@ -80,6 +92,38 @@ const SearchTriggerButton = styled(Button)`
80
92
  }
81
93
  `;
82
94
 
95
+ // The hidden copy of the wider label keeps the slot the same width before and after
96
+ // hydration on every platform, so the trigger does not shift when the label appears.
97
+ const SearchTriggerShortcut = styled.span`
98
+ display: inline-flex;
99
+ flex-direction: column;
100
+ align-items: flex-end;
101
+
102
+ &::after {
103
+ content: '${SHORTCUT_LABEL}';
104
+ height: 0;
105
+ overflow: hidden;
106
+ visibility: hidden;
107
+ }
108
+ `;
109
+
110
+ const shortcutAppear = keyframes`
111
+ from {
112
+ opacity: 0;
113
+ filter: blur(2px);
114
+ transform: translateY(3px);
115
+ }
116
+ `;
117
+
118
+ const SearchTriggerShortcutLabel = styled.span`
119
+ animation: ${shortcutAppear} var(--search-trigger-shortcut-appear-duration)
120
+ var(--search-trigger-shortcut-appear-easing);
121
+
122
+ @media (prefers-reduced-motion: reduce) {
123
+ animation: none;
124
+ }
125
+ `;
126
+
83
127
  const SearchTriggerInput = styled.div`
84
128
  display: none;
85
129
  align-items: center;
@@ -145,6 +145,8 @@ export const search = css`
145
145
  --search-trigger-bg-color: var(--navbar-bg-color);
146
146
  --search-trigger-icon-size: 16px;
147
147
  --search-trigger-line-height: var(--line-height-base);
148
+ --search-trigger-shortcut-appear-duration: 300ms;
149
+ --search-trigger-shortcut-appear-easing: ease-out;
148
150
 
149
151
  /**
150
152
  * @tokens AI Search
@@ -199,8 +201,21 @@ export const search = css`
199
201
  --search-ai-suggestions-title-font-weight: var(--font-weight-light);
200
202
  --search-ai-suggestions-text-color: var(--text-color-description);
201
203
 
202
- --search-ai-thinking-dots-gap: 4px;
203
- --search-ai-thinking-dots-padding: 4px 0;
204
+ --search-ai-activity-font-size: var(--font-size-base);
205
+ --search-ai-activity-line-height: var(--line-height-sm);
206
+ --search-ai-activity-count-font-size: var(--font-size-sm);
207
+ --search-ai-activity-count-bg-color: var(--border-color-secondary);
208
+ --search-ai-activity-text-color: var(--text-color-description);
209
+ --search-ai-activity-text-color-hover: var(--text-color-primary);
210
+ --search-ai-activity-detail-color: var(--text-color-secondary);
211
+ --search-ai-activity-shimmer-color: var(--text-color-primary);
212
+ --search-ai-activity-rail-color: var(--border-color-primary);
213
+ --search-ai-activity-icon-size: 14px;
214
+ --search-ai-activity-fade-duration: 200ms;
215
+ --search-ai-activity-expand-duration: 250ms;
216
+ --search-ai-activity-shimmer-duration: 2s;
217
+ --search-ai-activity-easing: cubic-bezier(0.32, 0.72, 0, 1);
218
+
204
219
  --search-ai-thinking-dot-size: 6px;
205
220
  --search-ai-thinking-dot-color: var(--search-ai-gradient);
206
221
 
@@ -5,34 +5,43 @@ import type { ForwardedRef, ReactElement } from 'react';
5
5
  import type { SegmentedProps } from '@redocly/theme/core/types';
6
6
 
7
7
  import { typedMemo } from '@redocly/theme/core/hoc/typed-memo';
8
+ import { useTabList } from '@redocly/theme/core/hooks';
8
9
 
9
10
  function SegmentedComponent<T>(
10
11
  { options, onChange, value, className = '', size = 'regular' }: SegmentedProps<T>,
11
12
  ref?: ForwardedRef<HTMLDivElement>,
12
13
  ): ReactElement {
14
+ const { tabListProps, getTabProps } = useTabList({
15
+ count: options.length,
16
+ activeIndex: options.findIndex((opt) => value == opt.value),
17
+ onChange: (index) => onChange(options[index]),
18
+ });
19
+
13
20
  return (
14
21
  <SegmentedGroup
15
22
  ref={ref}
16
23
  data-component-name="Segmented/Segmented"
17
24
  className={`tag-grey ${size} ${className}`}
18
- role="tablist"
25
+ {...tabListProps}
19
26
  $size={size}
20
27
  >
21
- {options.map((opt, index) => (
22
- <React.Fragment key={index}>
23
- {opt.divider}
24
- <SegmentedItem
25
- key={opt.label}
26
- role="tab"
27
- title={opt.label}
28
- onClick={() => onChange(opt)}
29
- $isActive={value == opt.value}
30
- $size={size}
31
- >
32
- {opt.element || opt.label}
33
- </SegmentedItem>
34
- </React.Fragment>
35
- ))}
28
+ {options.map((opt, index) => {
29
+ const { 'aria-controls': _noPanel, ...tabProps } = getTabProps(index);
30
+ return (
31
+ <React.Fragment key={index}>
32
+ {opt.divider}
33
+ <SegmentedItem
34
+ key={opt.label}
35
+ {...tabProps}
36
+ title={opt.label}
37
+ $isActive={value == opt.value}
38
+ $size={size}
39
+ >
40
+ {opt.element || opt.label}
41
+ </SegmentedItem>
42
+ </React.Fragment>
43
+ );
44
+ })}
36
45
  </SegmentedGroup>
37
46
  );
38
47
  }
@@ -63,6 +63,7 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
63
63
  const [filteredOptions, setFilteredOptions] = useState<SelectOption<T>[]>(options);
64
64
  const [stickyInputValue, setStickyInputValue] = useState<string>(placeholder || '');
65
65
  const inputId = useId();
66
+ const listboxId = `${inputId}-listbox`;
66
67
 
67
68
  useOutsideClick(selectRef, () => {
68
69
  setDropdownActive(false);
@@ -189,7 +190,8 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
189
190
  return (
190
191
  <SelectInput
191
192
  id={inputId}
192
- listboxId={inputId}
193
+ listboxId={listboxId}
194
+ expanded={dropdownActive}
193
195
  selectedOptions={selectedOptions}
194
196
  searchValue={searchValue}
195
197
  placeholder={placeholder}
@@ -223,10 +225,14 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
223
225
  setDropdownActive(!dropdownActive);
224
226
  }
225
227
  }}
226
- tabIndex={0}
227
- aria-haspopup="listbox"
228
- aria-expanded={dropdownActive}
229
- aria-label="Select option"
228
+ tabIndex={searchable ? undefined : 0}
229
+ {...(!searchable && {
230
+ role: 'combobox',
231
+ 'aria-haspopup': 'listbox' as const,
232
+ 'aria-expanded': dropdownActive,
233
+ 'aria-controls': listboxId,
234
+ 'aria-label': 'Select option',
235
+ })}
230
236
  onFocus={(e) => {
231
237
  if (e.target === selectRef.current) {
232
238
  selectInputRef.current?.focus();
@@ -245,7 +251,7 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
245
251
  alignment={alignment}
246
252
  active={!renderInput ? dropdownActive : undefined}
247
253
  >
248
- <SelectDropdownMenu role="listbox" footer={footer}>
254
+ <SelectDropdownMenu id={listboxId} role="listbox" footer={footer}>
249
255
  {filteredOptions.length === 0 ? (
250
256
  <DropdownMenuItem disabled>
251
257
  {translate('select.noResults', 'No results')}
@@ -6,6 +6,7 @@ import type { SelectOption } from '@redocly/theme/core/types';
6
6
  import { Tag } from '@redocly/theme/components/Tag/Tag';
7
7
  import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
8
8
  import { Button } from '@redocly/theme/components/Button/Button';
9
+ import { assignRef } from '@redocly/theme/core/utils';
9
10
 
10
11
  type SelectInputProps<T> = {
11
12
  id?: string;
@@ -22,6 +23,7 @@ type SelectInputProps<T> = {
22
23
  placeholder?: string;
23
24
  multiple?: boolean;
24
25
  searchable?: boolean;
26
+ expanded?: boolean;
25
27
  clearable?: boolean;
26
28
  inputRef?: React.ForwardedRef<HTMLInputElement>;
27
29
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
@@ -48,6 +50,7 @@ export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
48
50
  stickyValue,
49
51
  multiple,
50
52
  searchable,
53
+ expanded,
51
54
  clearable,
52
55
  clearHandler,
53
56
  searchHandler,
@@ -123,17 +126,15 @@ export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
123
126
  if (!input) return;
124
127
 
125
128
  inputRef.current = input;
126
-
127
- if (!forwardedInputRef) return;
128
-
129
- if (typeof forwardedInputRef === 'function') {
130
- forwardedInputRef(input);
131
- } else {
132
- forwardedInputRef.current = input;
133
- }
129
+ assignRef(forwardedInputRef, input);
134
130
  }}
135
131
  $width={multiple ? (!searchValue && selectedOptions.length ? '10px' : 'auto') : '100%'}
136
132
  tabIndex={0}
133
+ role="combobox"
134
+ aria-expanded={!!expanded}
135
+ aria-controls={listboxId}
136
+ aria-autocomplete="list"
137
+ aria-label="Select option"
137
138
  onFocus={(e) => {
138
139
  e.stopPropagation();
139
140
  }}
@@ -156,16 +157,7 @@ export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
156
157
  );
157
158
 
158
159
  return (
159
- <SelectInputWrapper
160
- id={id}
161
- onFocus={onFocusHandler}
162
- onClick={onClickHandler}
163
- role="button"
164
- aria-haspopup="listbox"
165
- aria-controls={listboxId}
166
- aria-owns={listboxId}
167
- aria-label="Select option"
168
- >
160
+ <SelectInputWrapper id={id} onFocus={onFocusHandler} onClick={onClickHandler}>
169
161
  {!onlyIcon && (
170
162
  <>
171
163
  <SelectInputValue>
@@ -84,8 +84,8 @@ const SidebarContent = styled.aside<{ $opened: boolean; $collapsed?: boolean }>`
84
84
  flex-direction: column;
85
85
  width: 100%;
86
86
  -webkit-font-smoothing: antialiased;
87
- top: calc(var(--navbar-height) + var(--banner-height));
88
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
87
+ top: var(--navbar-offset);
88
+ height: calc(100vh - var(--navbar-offset));
89
89
  overflow-x: hidden;
90
90
  ${({ $opened }) => `
91
91
  display: ${$opened ? 'flex' : 'none'}