@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
@@ -19,7 +19,6 @@ import { useConnectMCPButton, useThemeHooks } from '@redocly/theme/core/hooks';
19
19
  import { DEFAULT_MCP_OPTIONS } from '@redocly/theme/core/constants';
20
20
 
21
21
  type MenuOption = {
22
- key: MCPOption;
23
22
  icon: React.ComponentType;
24
23
  titleTranslationKey: string;
25
24
  titleDefault: string;
@@ -27,48 +26,50 @@ type MenuOption = {
27
26
  descriptionDefault: string;
28
27
  };
29
28
 
30
- const MENU_OPTIONS: MenuOption[] = [
31
- {
32
- key: 'cursor',
29
+ const MENU_OPTIONS: Record<MCPOption, MenuOption> = {
30
+ cursor: {
33
31
  icon: CursorIcon,
34
32
  titleTranslationKey: 'page.actions.connectMcp.cursor',
35
33
  titleDefault: 'Connect to Cursor',
36
34
  descriptionTranslationKey: 'page.actions.connectMcp.cursorDescription',
37
35
  descriptionDefault: 'Install MCP server on Cursor',
38
36
  },
39
- {
40
- key: 'vscode',
37
+ vscode: {
41
38
  icon: VSCodeIcon,
42
39
  titleTranslationKey: 'page.actions.connectMcp.vscode',
43
40
  titleDefault: 'Connect to VS Code',
44
41
  descriptionTranslationKey: 'page.actions.connectMcp.vscodeDescription',
45
42
  descriptionDefault: 'Install MCP server on VS Code',
46
43
  },
47
- {
48
- key: 'claude-code',
44
+ claude: {
45
+ icon: ClaudeIcon,
46
+ titleTranslationKey: 'page.actions.connectMcp.claude',
47
+ titleDefault: 'Connect to Claude',
48
+ descriptionTranslationKey: 'page.actions.connectMcp.claudeDescription',
49
+ descriptionDefault: 'Add MCP server to your Claude account',
50
+ },
51
+ 'claude-code': {
49
52
  icon: ClaudeIcon,
50
53
  titleTranslationKey: 'page.actions.connectMcp.claudeCode',
51
54
  titleDefault: 'Connect to Claude Code',
52
55
  descriptionTranslationKey: 'page.actions.connectMcp.claudeCodeDescription',
53
56
  descriptionDefault: 'Copy the Claude Code CLI command',
54
57
  },
55
- {
56
- key: 'codex',
58
+ codex: {
57
59
  icon: CodexIcon,
58
60
  titleTranslationKey: 'page.actions.connectMcp.codex',
59
61
  titleDefault: 'Connect to Codex CLI',
60
62
  descriptionTranslationKey: 'page.actions.connectMcp.codexDescription',
61
63
  descriptionDefault: 'Copy the Codex CLI command',
62
64
  },
63
- {
64
- key: 'copy',
65
+ copy: {
65
66
  icon: CopyIcon,
66
67
  titleTranslationKey: 'page.actions.connectMcp.copyConfig',
67
68
  titleDefault: 'Copy MCP Configuration',
68
69
  descriptionTranslationKey: 'page.actions.connectMcp.copyConfigDescription',
69
70
  descriptionDefault: 'Copy MCP JSON Configuration',
70
71
  },
71
- ];
72
+ };
72
73
 
73
74
  // Copy actions keep the dropdown open so the copied checkmark is visible.
74
75
  const COPY_OPTIONS: MCPOption[] = ['claude-code', 'codex', 'copy'];
@@ -89,7 +90,7 @@ export function ConnectMCPButton({
89
90
 
90
91
  const { copiedOption, visibleOptions, handleAction } = useConnectMCPButton({ options });
91
92
 
92
- const menuOptions = MENU_OPTIONS.filter((option) => visibleOptions.includes(option.key));
93
+ const menuOptions = visibleOptions.map((key) => ({ key, ...MENU_OPTIONS[key] }));
93
94
  const primaryOption = menuOptions[0];
94
95
  const dropdownOptions = menuOptions.slice(1);
95
96
 
@@ -124,7 +125,7 @@ export function ConnectMCPButton({
124
125
  >
125
126
  {dropdownOptions.length > 0
126
127
  ? ({ close }: { close: () => void }) => (
127
- <DropdownMenu>
128
+ <StyledDropdownMenu>
128
129
  {dropdownOptions.map((option) => {
129
130
  const Icon = option.icon;
130
131
  const showCheckmark = copiedOption === option.key;
@@ -156,7 +157,7 @@ export function ConnectMCPButton({
156
157
  </DropdownMenuItem>
157
158
  );
158
159
  })}
159
- </DropdownMenu>
160
+ </StyledDropdownMenu>
160
161
  )
161
162
  : null}
162
163
  </SplitButton>
@@ -164,6 +165,10 @@ export function ConnectMCPButton({
164
165
  );
165
166
  }
166
167
 
168
+ const StyledDropdownMenu = styled(DropdownMenu)`
169
+ --dropdown-menu-max-height: var(--connect-mcp-button-dropdown-max-height);
170
+ `;
171
+
167
172
  const ConnectMCPButtonWrapper = styled.div`
168
173
  display: inline-block;
169
174
  position: relative;
@@ -50,3 +50,7 @@ export const aiAssistantButton = css`
50
50
  // @tokens End
51
51
  `;
52
52
  /* eslint-enable theme/no-raw-colors-in-styles */
53
+
54
+ export const connectMcpButton = css`
55
+ --connect-mcp-button-dropdown-max-height: fit-content;
56
+ `;
@@ -162,9 +162,11 @@ export function Catalog(props: CatalogProps): JSX.Element {
162
162
  <CatalogPageContentWrapper>
163
163
  <CatalogTitleWrapper>
164
164
  <CatalogTitle data-translation-key={catalogConfig?.titleTranslationKey}>
165
- {catalogConfig?.titleTranslationKey
166
- ? translate(catalogConfig?.titleTranslationKey)
167
- : catalogConfig?.slug}{' '}
165
+ <span>
166
+ {catalogConfig?.titleTranslationKey
167
+ ? translate(catalogConfig?.titleTranslationKey)
168
+ : catalogConfig?.slug}
169
+ </span>{' '}
168
170
  </CatalogTitle>
169
171
  <CounterTag borderless>{entitiesCounter}</CounterTag>
170
172
  </CatalogTitleWrapper>
@@ -256,7 +258,7 @@ const CatalogDescription = styled.p`
256
258
  const CatalogPageWrapper = styled.div`
257
259
  --sidebar-width: var(--catalog-sidebar-width);
258
260
 
259
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
261
+ height: calc(100vh - var(--navbar-offset));
260
262
  display: flex;
261
263
  flex-direction: column;
262
264
  overflow: hidden;
@@ -3,5 +3,7 @@ import type { CatalogEntityRelationsGraphProps } from '@redocly/theme/components
3
3
  import { dynamic } from '@redocly/theme/core/utils';
4
4
 
5
5
  export const CatalogEntityRelationsGraph = dynamic<CatalogEntityRelationsGraphProps>(() =>
6
- import('./CatalogEntityRelationsGraph').then((mod) => mod.CatalogEntityRelationsGraph),
6
+ import('@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph').then(
7
+ (mod) => mod.CatalogEntityRelationsGraph,
8
+ ),
7
9
  );
@@ -164,10 +164,10 @@ export function CatalogEntityHistorySidebar({
164
164
 
165
165
  const SidebarOverlay = styled.div`
166
166
  position: fixed;
167
- top: calc(var(--navbar-height) + var(--banner-height));
167
+ top: var(--navbar-offset);
168
168
  left: 0;
169
169
  width: var(--sidebar-width);
170
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
170
+ height: calc(100vh - var(--navbar-offset));
171
171
  padding: var(--catalog-history-sidebar-padding);
172
172
  background-color: var(--catalog-history-sidebar-bg-color);
173
173
  border-right: 1px solid var(--catalog-history-sidebar-border-color);
@@ -120,7 +120,7 @@ const SplitViewWrapper = styled.div`
120
120
  const SchemaSampleWrapper = styled.div`
121
121
  flex: 1;
122
122
  position: sticky;
123
- top: calc(var(--navbar-height) + var(--banner-height) + var(--spacing-md));
123
+ top: calc(var(--navbar-offset) + var(--spacing-md));
124
124
  align-self: flex-start;
125
125
  padding-top: var(--spacing-sm);
126
126
  `;
@@ -96,30 +96,28 @@ export function CatalogFilterCheckboxes({
96
96
  <FilterOptions>
97
97
  {filteredOptions.map(({ value, count }) => {
98
98
  const id = 'filter--' + filter.property + '--' + value;
99
+ const checked =
100
+ filter.selectedOptions instanceof Set
101
+ ? filter.selectedOptions.has(value) ||
102
+ filter.selectedOptions.has(value?.toLowerCase())
103
+ : false;
99
104
  return (
100
- <FilterCheckboxOption
101
- key={id}
102
- role="link"
103
- onClick={() => {
104
- filter.toggleOption(value);
105
- telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
106
- {
107
- ...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
108
- category: filter.property,
109
- value: value,
110
- },
111
- ]);
112
- }}
113
- >
114
- <CheckboxIcon
115
- checked={
116
- filter.selectedOptions instanceof Set
117
- ? filter.selectedOptions.has(value) ||
118
- filter.selectedOptions.has(value?.toLowerCase())
119
- : false
120
- }
121
- />
105
+ <FilterCheckboxOption key={id}>
106
+ <CheckboxIcon checked={checked} />
122
107
  <FilterOptionLabel data-translation-key={value}>
108
+ <FilterCheckboxInput
109
+ checked={checked}
110
+ onChange={() => {
111
+ filter.toggleOption(value);
112
+ telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
113
+ {
114
+ ...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
115
+ category: filter.property,
116
+ value: value,
117
+ },
118
+ ]);
119
+ }}
120
+ />
123
121
  {highlightText(changeTextCasing(translate(value), filterValuesCasing) || '')}
124
122
  </FilterOptionLabel>
125
123
  {showCounter && <CounterTag borderless>{count}</CounterTag>}
@@ -168,6 +166,23 @@ const HighlightedText = styled.span`
168
166
 
169
167
  const FilterCheckboxOption = styled(FilterOption)`
170
168
  padding-left: var(--filter-option-checkbox-padding-left);
169
+
170
+ &:has(input:focus-visible) {
171
+ outline: 1px solid var(--button-border-color-focused);
172
+ outline-offset: -1px;
173
+ }
174
+ `;
175
+
176
+ const FilterCheckboxInput = styled.input.attrs({ type: 'checkbox' })`
177
+ position: absolute;
178
+ width: 1px;
179
+ height: 1px;
180
+ margin: -1px;
181
+ padding: 0;
182
+ overflow: hidden;
183
+ clip: rect(0 0 0 0);
184
+ white-space: nowrap;
185
+ border: 0;
171
186
  `;
172
187
 
173
188
  const FilterSearchWrapper = styled.div`
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from 'react';
1
+ import React, { useMemo, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -19,6 +19,7 @@ export function CatalogFilterDateRange({
19
19
  filter,
20
20
  className,
21
21
  }: CatalogFilterDateRangeProps): JSX.Element {
22
+ const [today] = useState(() => new Date());
22
23
  const { useTranslate } = useThemeHooks();
23
24
  const { translate } = useTranslate();
24
25
 
@@ -60,7 +61,7 @@ export function CatalogFilterDateRange({
60
61
  monthPlaceholder="MM"
61
62
  yearPlaceholder="YYYY"
62
63
  value={from}
63
- maxDate={new Date()}
64
+ maxDate={today}
64
65
  onChange={(from) => {
65
66
  if (Array.isArray(from)) return;
66
67
  filter.selectOption({
@@ -23,7 +23,7 @@ export function CatalogMobileFiltersPanel({
23
23
 
24
24
  const CatalogMobileFiltersPanelWrapper = styled.div`
25
25
  width: 100%;
26
- max-height: calc(100vh - var(--navbar-height) - var(--banner-height));
26
+ max-height: calc(100vh - var(--navbar-offset));
27
27
  overflow-y: auto;
28
28
  background: var(--sidebar-bg-color);
29
29
  display: flex;
@@ -27,10 +27,10 @@ export function CatalogMobileFiltersPanelOverlay({
27
27
  const CatalogMobileFiltersPanelOverlayWrapper = styled.div`
28
28
  display: none;
29
29
  position: fixed;
30
- top: calc(var(--navbar-height) + var(--banner-height));
30
+ top: var(--navbar-offset);
31
31
  left: 0;
32
32
  width: 100%;
33
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
33
+ height: calc(100vh - var(--navbar-offset));
34
34
  z-index: 3;
35
35
  background: var(--bg-color);
36
36
  flex-direction: column;
@@ -10,8 +10,7 @@ import { Tooltip } from '@redocly/theme/components/Tooltip/Tooltip';
10
10
  import type { ReportButtonProps } from '@redocly/theme/core/hooks';
11
11
  import { useThemeHooks, useThemeConfig } from '@redocly/theme/core/hooks';
12
12
  import { DeselectIcon } from '@redocly/theme/icons/DeselectIcon/DeselectIcon';
13
- import { MaximizeIcon } from '@redocly/theme/icons/MaximizeIcon/MaximizeIcon';
14
- import { MinimizeIcon } from '@redocly/theme/icons/MinimizeIcon/MinimizeIcon';
13
+ import { ExpandCollapseIcon } from '@redocly/theme/icons/ExpandCollapseIcon/ExpandCollapseIcon';
15
14
  import { SelectIcon } from '@redocly/theme/icons/SelectIcon/SelectIcon';
16
15
  import { WarningSquareIcon } from '@redocly/theme/icons/WarningSquareIcon/WarningSquareIcon';
17
16
  import { Button } from '@redocly/theme/components/Button/Button';
@@ -116,16 +115,14 @@ export function CodeBlockControls({
116
115
  variant="text"
117
116
  size="small"
118
117
  data-testid="expand-all"
119
- icon={controlsType === 'icon' ? <MaximizeIcon /> : undefined}
118
+ icon={controlsType === 'icon' ? <ExpandCollapseIcon /> : undefined}
120
119
  aria-label="Expand all"
121
120
  onClick={expand?.onClick}
122
121
  >
123
122
  {controlsType !== 'icon' && (expand?.label || 'Expand all')}
124
123
  </ControlButton>
125
124
  </Tooltip>
126
- ) : null}
127
-
128
- {collapse && !codeSnippet?.collapse?.hide ? (
125
+ ) : collapse && !codeSnippet?.collapse?.hide ? (
129
126
  <Tooltip
130
127
  tip={
131
128
  collapse.props?.tooltip ||
@@ -138,7 +135,7 @@ export function CodeBlockControls({
138
135
  variant="text"
139
136
  size="small"
140
137
  data-testid="collapse-all"
141
- icon={controlsType === 'icon' ? <MinimizeIcon /> : undefined}
138
+ icon={controlsType === 'icon' ? <ExpandCollapseIcon $collapse /> : undefined}
142
139
  onClick={collapse?.onClick}
143
140
  aria-label="Collapse all"
144
141
  >
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ import type { JSX } from 'react';
4
+
5
+ import { ConsentBanner } from '@redocly/theme/components/Consent/ConsentBanner';
6
+ import { ConsentDialog } from '@redocly/theme/components/Consent/ConsentDialog';
7
+ import { useConsentTelemetry } from '@redocly/theme/core/hooks';
8
+
9
+ export function Consent(): JSX.Element {
10
+ useConsentTelemetry();
11
+
12
+ return (
13
+ <>
14
+ <ConsentBanner />
15
+ <ConsentDialog />
16
+ </>
17
+ );
18
+ }
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import styled, { keyframes } from 'styled-components';
3
+
4
+ import type { JSX } from 'react';
5
+
6
+ import { Button } from '@redocly/theme/components/Button/Button';
7
+ import { Link } from '@redocly/theme/components/Link/Link';
8
+ import { useThemeHooks } from '@redocly/theme/core/hooks';
9
+
10
+ export function ConsentBanner(): JSX.Element | null {
11
+ const { useConsent, useTranslate } = useThemeHooks();
12
+ const consent = useConsent();
13
+ const { translate } = useTranslate();
14
+
15
+ if (!consent.enabled || consent.mode !== 'opt-in' || consent.decided || consent.isDialogOpen) {
16
+ return null;
17
+ }
18
+
19
+ const title = translate('consent.title', 'We value your privacy');
20
+
21
+ return (
22
+ <BannerWrapper data-component-name="Consent/ConsentBanner" role="region" aria-label={title}>
23
+ <Title>{title}</Title>
24
+ <Message>
25
+ {translate(
26
+ 'consent.message',
27
+ 'By selecting "Accept all cookies", you agree to the use of cookies to improve site navigation, understand how our site is used, and support our marketing efforts. Select "Customize" to choose which types of cookies you allow.',
28
+ )}{' '}
29
+ {consent.config?.privacyPolicyUrl ? (
30
+ <Link to={consent.config.privacyPolicyUrl} external>
31
+ {translate('consent.privacyPolicy', 'Privacy policy')}
32
+ </Link>
33
+ ) : null}
34
+ </Message>
35
+ <Actions>
36
+ <MainActions>
37
+ <Button variant="outlined" onClick={consent.reject}>
38
+ {translate('consent.rejectAll', 'Reject all')}
39
+ </Button>
40
+ <Button variant="primary" onClick={consent.accept}>
41
+ {translate('consent.acceptAllCookies', 'Accept all cookies')}
42
+ </Button>
43
+ </MainActions>
44
+ <Button variant="text" onClick={consent.openDialog}>
45
+ {translate('consent.customize', 'Customize')}
46
+ </Button>
47
+ </Actions>
48
+ </BannerWrapper>
49
+ );
50
+ }
51
+
52
+ const slideUp = keyframes`
53
+ from {
54
+ opacity: 0;
55
+ transform: translateY(16px);
56
+ }
57
+ to {
58
+ opacity: 1;
59
+ transform: translateY(0);
60
+ }
61
+ `;
62
+
63
+ const BannerWrapper = styled.div`
64
+ position: fixed;
65
+ left: var(--consent-banner-offset);
66
+ bottom: var(--consent-banner-offset);
67
+ z-index: var(--consent-banner-z-index);
68
+ display: flex;
69
+ flex-direction: column;
70
+ gap: var(--consent-banner-gap);
71
+ width: var(--consent-banner-width);
72
+ max-width: calc(100vw - 2 * var(--consent-banner-offset));
73
+ padding: var(--consent-banner-padding);
74
+ border: 1px solid var(--consent-banner-border-color);
75
+ border-radius: var(--consent-banner-border-radius);
76
+ background: var(--consent-banner-bg-color);
77
+ color: var(--consent-banner-text-color);
78
+ box-shadow: var(--consent-banner-box-shadow);
79
+ font-family: var(--font-family-base);
80
+
81
+ @media (prefers-reduced-motion: no-preference) {
82
+ animation: ${slideUp} 240ms ease-out;
83
+ }
84
+ `;
85
+
86
+ const Title = styled.h2`
87
+ margin: 0;
88
+ font-size: var(--consent-banner-title-font-size);
89
+ font-weight: var(--font-weight-bold);
90
+ `;
91
+
92
+ const Message = styled.p`
93
+ margin: 0;
94
+ color: var(--text-color-secondary);
95
+ font-size: var(--consent-banner-font-size);
96
+ `;
97
+
98
+ const Actions = styled.div`
99
+ display: flex;
100
+ flex-wrap: wrap;
101
+ gap: var(--consent-banner-gap);
102
+ align-items: center;
103
+ justify-content: space-between;
104
+ `;
105
+
106
+ const MainActions = styled.div`
107
+ display: flex;
108
+ flex-wrap: wrap;
109
+ gap: var(--consent-banner-gap);
110
+ `;
@@ -0,0 +1,210 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { JSX } from 'react';
5
+ import type { UseConsentResult } from '@redocly/theme/core/types';
6
+ import type { ConsentDraft } from '@redocly/theme/core/hooks';
7
+
8
+ import { Button } from '@redocly/theme/components/Button/Button';
9
+ import { Link } from '@redocly/theme/components/Link/Link';
10
+ import { Portal } from '@redocly/theme/components/Portal/Portal';
11
+ import { Switch } from '@redocly/theme/components/Switch/Switch';
12
+ import { useConsentDialog, useThemeHooks } from '@redocly/theme/core/hooks';
13
+ import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
14
+
15
+ const noop = () => {};
16
+
17
+ export function ConsentDialog(): JSX.Element | null {
18
+ const { useConsent } = useThemeHooks();
19
+ const consent = useConsent();
20
+
21
+ if (!consent.enabled || !consent.isDialogOpen) {
22
+ return null;
23
+ }
24
+
25
+ return <ConsentDialogContent consent={consent} />;
26
+ }
27
+
28
+ function ConsentDialogContent({ consent }: { consent: UseConsentResult }): JSX.Element {
29
+ const { useTranslate } = useThemeHooks();
30
+ const { translate } = useTranslate();
31
+ const { draft, setCategory, dialogRef, close, save, categories } = useConsentDialog(consent);
32
+
33
+ return (
34
+ <Portal>
35
+ <Overlay
36
+ className="scroll-lock"
37
+ data-component-name="Consent/ConsentDialog"
38
+ onMouseDown={(event) => {
39
+ if (event.target === event.currentTarget) close();
40
+ }}
41
+ >
42
+ <Dialog
43
+ ref={dialogRef}
44
+ role="dialog"
45
+ aria-modal="true"
46
+ aria-labelledby="redocly-consent-dialog-title"
47
+ tabIndex={-1}
48
+ >
49
+ <TitleRow>
50
+ <Title id="redocly-consent-dialog-title">
51
+ {translate('consent.dialog.title', 'Cookie preferences')}
52
+ </Title>
53
+ <Button
54
+ variant="ghost"
55
+ size="small"
56
+ icon={<CloseIcon />}
57
+ aria-label={translate('consent.dialog.close', 'Close')}
58
+ onClick={close}
59
+ />
60
+ </TitleRow>
61
+ <Description>
62
+ {translate(
63
+ 'consent.dialog.description',
64
+ 'Choose which cookies this site may use. You can change your choice at any time.',
65
+ )}{' '}
66
+ {consent.config?.privacyPolicyUrl ? (
67
+ <Link to={consent.config.privacyPolicyUrl} external>
68
+ {translate('consent.privacyPolicy', 'Privacy policy')}
69
+ </Link>
70
+ ) : null}
71
+ </Description>
72
+ {categories.map((category) => {
73
+ const gpcLocked = category.id === 'marketing' && consent.gpc;
74
+ return (
75
+ <Row key={category.id}>
76
+ <RowText>
77
+ <RowTitle>
78
+ {translate(category.titleTranslationKey, category.titleDefault)}
79
+ </RowTitle>
80
+ <RowDescription>
81
+ {translate(category.descriptionTranslationKey, category.descriptionDefault)}
82
+ </RowDescription>
83
+ {gpcLocked ? (
84
+ <GpcNotice>
85
+ {translate(
86
+ 'consent.gpcNotice',
87
+ 'Your browser asked us not to share your data, so this stays off.',
88
+ )}
89
+ </GpcNotice>
90
+ ) : null}
91
+ </RowText>
92
+ {category.locked ? (
93
+ <SwitchGroup role="group" aria-label={translate('consent.alwaysOn', 'Always on')}>
94
+ <Switch value={true} disabled onChange={noop} />
95
+ </SwitchGroup>
96
+ ) : gpcLocked ? (
97
+ <SwitchGroup
98
+ role="group"
99
+ aria-label={translate('consent.alwaysOff', 'Always off')}
100
+ >
101
+ <Switch value={false} disabled onChange={noop} />
102
+ </SwitchGroup>
103
+ ) : (
104
+ <Switch
105
+ value={draft[category.id as keyof ConsentDraft]}
106
+ onChange={(value) => setCategory(category.id as keyof ConsentDraft, value)}
107
+ />
108
+ )}
109
+ </Row>
110
+ );
111
+ })}
112
+ <Actions>
113
+ <Button variant="outlined" onClick={consent.reject}>
114
+ {translate('consent.rejectAll', 'Reject all')}
115
+ </Button>
116
+ <Spacer />
117
+ <Button variant="outlined" onClick={consent.accept}>
118
+ {translate('consent.acceptAll', 'Accept all')}
119
+ </Button>
120
+ <Button variant="primary" onClick={save}>
121
+ {translate('consent.savePreferences', 'Save preferences')}
122
+ </Button>
123
+ </Actions>
124
+ </Dialog>
125
+ </Overlay>
126
+ </Portal>
127
+ );
128
+ }
129
+
130
+ const Overlay = styled.div`
131
+ position: fixed;
132
+ inset: 0;
133
+ z-index: var(--z-index-overlay);
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ background: var(--bg-color-modal-overlay);
138
+ font-family: var(--font-family-base);
139
+ `;
140
+
141
+ const Dialog = styled.div`
142
+ width: var(--consent-dialog-width);
143
+ max-width: var(--consent-dialog-max-width);
144
+ padding: var(--consent-dialog-padding);
145
+ border-radius: var(--consent-dialog-border-radius);
146
+ background: var(--consent-dialog-bg-color);
147
+ box-shadow: var(--consent-dialog-box-shadow);
148
+ `;
149
+
150
+ const TitleRow = styled.div`
151
+ display: flex;
152
+ gap: var(--spacing-xs);
153
+ align-items: flex-start;
154
+ justify-content: space-between;
155
+ `;
156
+
157
+ const Title = styled.h2`
158
+ margin: 0 0 var(--spacing-xs);
159
+ font-size: var(--font-size-lg);
160
+ `;
161
+
162
+ const Description = styled.p`
163
+ margin: 0 0 var(--spacing-base);
164
+ color: var(--consent-dialog-description-color);
165
+ font-size: var(--font-size-sm);
166
+ `;
167
+
168
+ const Row = styled.div`
169
+ display: flex;
170
+ gap: var(--spacing-base);
171
+ align-items: flex-start;
172
+ padding: var(--spacing-sm) 0;
173
+ border-top: 1px solid var(--consent-dialog-row-border-color);
174
+ `;
175
+
176
+ const RowText = styled.div`
177
+ flex: 1;
178
+ `;
179
+
180
+ const RowTitle = styled.div`
181
+ font-size: var(--font-size-base);
182
+ font-weight: var(--font-weight-bold);
183
+ `;
184
+
185
+ const RowDescription = styled.div`
186
+ color: var(--consent-dialog-description-color);
187
+ font-size: var(--font-size-sm);
188
+ `;
189
+
190
+ const GpcNotice = styled.div`
191
+ color: var(--consent-dialog-description-color);
192
+ font-size: var(--font-size-sm);
193
+ `;
194
+
195
+ const SwitchGroup = styled.div`
196
+ flex: none;
197
+ `;
198
+
199
+ const Actions = styled.div`
200
+ display: flex;
201
+ flex-wrap: wrap;
202
+ gap: var(--spacing-xs);
203
+ margin-top: var(--spacing-base);
204
+ padding-top: var(--spacing-base);
205
+ border-top: 1px solid var(--consent-dialog-row-border-color);
206
+ `;
207
+
208
+ const Spacer = styled.span`
209
+ flex: 1;
210
+ `;