@redocly/theme 0.59.0-rc.1 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +7 -1
  2. package/lib/components/Buttons/AIAssistantButton.js +6 -2
  3. package/lib/components/Buttons/ConnectMCPButton.d.ts +8 -0
  4. package/lib/components/Buttons/ConnectMCPButton.js +145 -0
  5. package/lib/components/Buttons/variables.d.ts +1 -0
  6. package/lib/components/Buttons/variables.js +42 -2
  7. package/lib/components/Catalog/CatalogEntity/CatalogEntityInfoBar.js +1 -0
  8. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.js +1 -1
  9. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.js +1 -1
  10. package/lib/components/Catalog/CatalogEntityIcon.js +2 -1
  11. package/lib/components/Catalog/CatalogFilter/CatalogFilter.js +4 -0
  12. package/lib/components/Catalog/CatalogTagsWithTooltip.js +1 -1
  13. package/lib/components/Catalog/variables.js +1 -1
  14. package/lib/components/Dropdown/Dropdown.d.ts +16 -2
  15. package/lib/components/Dropdown/Dropdown.js +5 -5
  16. package/lib/components/Menu/MenuItem.js +1 -1
  17. package/lib/components/Navbar/NavbarItem.js +3 -3
  18. package/lib/components/PageActions/PageActions.js +4 -1
  19. package/lib/components/PageActions/variables.js +2 -0
  20. package/lib/components/Search/FilterFields/SearchFilterFieldTags.js +1 -2
  21. package/lib/components/Search/SearchAiActionButtons.d.ts +10 -0
  22. package/lib/components/Search/SearchAiActionButtons.js +43 -0
  23. package/lib/components/Search/SearchAiConversationInput.d.ts +3 -1
  24. package/lib/components/Search/SearchAiConversationInput.js +39 -7
  25. package/lib/components/Search/SearchAiDialog.d.ts +3 -6
  26. package/lib/components/Search/SearchAiDialog.js +20 -9
  27. package/lib/components/Search/SearchAiMessage.d.ts +9 -5
  28. package/lib/components/Search/SearchAiMessage.js +146 -22
  29. package/lib/components/Search/SearchAiNegativeFeedbackForm.d.ts +8 -0
  30. package/lib/components/Search/SearchAiNegativeFeedbackForm.js +169 -0
  31. package/lib/components/Search/SearchDialog.js +36 -5
  32. package/lib/components/Search/SearchGroups.js +2 -2
  33. package/lib/components/Search/variables.js +36 -64
  34. package/lib/components/Segmented/Segmented.d.ts +1 -8
  35. package/lib/components/Segmented/Segmented.js +3 -1
  36. package/lib/components/Select/SelectInput.js +1 -1
  37. package/lib/components/Select/variables.js +2 -2
  38. package/lib/components/Tag/Tag.d.ts +2 -1
  39. package/lib/components/Tag/Tag.js +66 -17
  40. package/lib/components/Tag/variables.dark.js +135 -36
  41. package/lib/components/Tag/variables.js +78 -61
  42. package/lib/core/constants/index.d.ts +1 -0
  43. package/lib/core/constants/index.js +1 -0
  44. package/lib/core/constants/mcp.d.ts +1 -0
  45. package/lib/core/constants/mcp.js +5 -0
  46. package/lib/core/constants/search.d.ts +5 -4
  47. package/lib/core/constants/search.js +4 -5
  48. package/lib/core/hooks/index.d.ts +3 -0
  49. package/lib/core/hooks/index.js +3 -0
  50. package/lib/core/hooks/menu/use-nested-menu.js +1 -1
  51. package/lib/core/hooks/search/use-feedback-tooltip.d.ts +6 -0
  52. package/lib/core/hooks/search/use-feedback-tooltip.js +26 -0
  53. package/lib/core/hooks/use-connect-mcp-button.d.ts +13 -0
  54. package/lib/core/hooks/use-connect-mcp-button.js +50 -0
  55. package/lib/core/hooks/use-mcp-config.d.ts +9 -0
  56. package/lib/core/hooks/use-mcp-config.js +27 -0
  57. package/lib/core/hooks/use-page-actions.d.ts +1 -1
  58. package/lib/core/hooks/use-page-actions.js +98 -95
  59. package/lib/core/hooks/use-product-picker.js +2 -1
  60. package/lib/core/hooks/use-tabs.d.ts +3 -2
  61. package/lib/core/hooks/use-tabs.js +115 -57
  62. package/lib/core/hooks/use-telemetry-fallback.d.ts +10 -8
  63. package/lib/core/hooks/use-telemetry-fallback.js +10 -8
  64. package/lib/core/openapi/index.d.ts +1 -0
  65. package/lib/core/styles/dark.js +4 -0
  66. package/lib/core/styles/global.js +5 -0
  67. package/lib/core/types/hooks.d.ts +2 -2
  68. package/lib/core/types/index.d.ts +1 -0
  69. package/lib/core/types/index.js +1 -0
  70. package/lib/core/types/l10n.d.ts +1 -1
  71. package/lib/core/types/mcp.d.ts +6 -0
  72. package/lib/core/types/mcp.js +3 -0
  73. package/lib/core/types/search.d.ts +11 -4
  74. package/lib/core/types/search.js +6 -0
  75. package/lib/core/types/segmented.d.ts +12 -0
  76. package/lib/core/types/segmented.js +3 -0
  77. package/lib/core/utils/frontmatter-translate.d.ts +6 -0
  78. package/lib/core/utils/frontmatter-translate.js +14 -0
  79. package/lib/core/utils/index.d.ts +2 -0
  80. package/lib/core/utils/index.js +2 -0
  81. package/lib/core/utils/mcp.d.ts +2 -0
  82. package/lib/core/utils/mcp.js +31 -0
  83. package/lib/icons/AiStarsGradientIcon/AiStarsGradientIcon.js +44 -4
  84. package/lib/icons/AiStarsIcon/AiStarsIcon.js +11 -2
  85. package/lib/icons/ConnectIcon/ConnectIcon.d.ts +9 -0
  86. package/lib/icons/ConnectIcon/ConnectIcon.js +17 -0
  87. package/lib/icons/CubeIcon/CubeIcon.d.ts +9 -0
  88. package/lib/icons/CubeIcon/CubeIcon.js +17 -0
  89. package/lib/icons/HashtagIcon/HashtagIcon.d.ts +9 -0
  90. package/lib/icons/HashtagIcon/HashtagIcon.js +22 -0
  91. package/lib/icons/RedoclyIcon/RedoclyIcon.js +4 -7
  92. package/lib/icons/ThumbDownFilledIcon/ThumbDownFilledIcon.d.ts +9 -0
  93. package/lib/icons/ThumbDownFilledIcon/ThumbDownFilledIcon.js +34 -0
  94. package/lib/icons/ThumbUpFilledIcon/ThumbUpFilledIcon.d.ts +9 -0
  95. package/lib/icons/ThumbUpFilledIcon/ThumbUpFilledIcon.js +34 -0
  96. package/lib/icons/VSCodeIcon/VSCodeIcon.d.ts +9 -0
  97. package/lib/icons/VSCodeIcon/VSCodeIcon.js +17 -0
  98. package/lib/index.d.ts +1 -2
  99. package/lib/index.js +1 -2
  100. package/lib/markdoc/components/Cards/Card.js +1 -28
  101. package/lib/markdoc/components/ConnectMCP/ConnectMCP.d.ts +8 -0
  102. package/lib/markdoc/components/ConnectMCP/ConnectMCP.js +19 -0
  103. package/lib/markdoc/components/Tabs/TabList.d.ts +3 -1
  104. package/lib/markdoc/components/Tabs/TabList.js +197 -47
  105. package/lib/markdoc/components/Tabs/Tabs.d.ts +2 -1
  106. package/lib/markdoc/components/Tabs/Tabs.js +57 -12
  107. package/lib/markdoc/components/default.d.ts +1 -0
  108. package/lib/markdoc/components/default.js +1 -0
  109. package/lib/markdoc/default.d.ts +6 -0
  110. package/lib/markdoc/default.js +2 -0
  111. package/lib/markdoc/tags/card.js +0 -1
  112. package/lib/markdoc/tags/connect-mcp.d.ts +2 -0
  113. package/lib/markdoc/tags/connect-mcp.js +27 -0
  114. package/package.json +6 -6
  115. package/src/components/Buttons/AIAssistantButton.tsx +6 -2
  116. package/src/components/Buttons/ConnectMCPButton.tsx +180 -0
  117. package/src/components/Buttons/variables.ts +42 -1
  118. package/src/components/Catalog/CatalogEntity/CatalogEntityInfoBar.tsx +1 -0
  119. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +1 -1
  120. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx +1 -1
  121. package/src/components/Catalog/CatalogEntityIcon.tsx +2 -1
  122. package/src/components/Catalog/CatalogFilter/CatalogFilter.tsx +5 -0
  123. package/src/components/Catalog/CatalogTagsWithTooltip.tsx +1 -5
  124. package/src/components/Catalog/variables.ts +1 -1
  125. package/src/components/Dropdown/Dropdown.tsx +84 -79
  126. package/src/components/Menu/MenuItem.tsx +1 -0
  127. package/src/components/Navbar/NavbarItem.tsx +6 -5
  128. package/src/components/PageActions/PageActions.tsx +5 -1
  129. package/src/components/PageActions/variables.ts +2 -0
  130. package/src/components/Search/FilterFields/SearchFilterFieldTags.tsx +3 -3
  131. package/src/components/Search/SearchAiActionButtons.tsx +76 -0
  132. package/src/components/Search/SearchAiConversationInput.tsx +61 -18
  133. package/src/components/Search/SearchAiDialog.tsx +52 -23
  134. package/src/components/Search/SearchAiMessage.tsx +172 -43
  135. package/src/components/Search/SearchAiNegativeFeedbackForm.tsx +210 -0
  136. package/src/components/Search/SearchDialog.tsx +49 -13
  137. package/src/components/Search/SearchGroups.tsx +2 -0
  138. package/src/components/Search/variables.ts +36 -64
  139. package/src/components/Segmented/Segmented.tsx +15 -20
  140. package/src/components/Select/SelectInput.tsx +1 -0
  141. package/src/components/Select/variables.ts +2 -2
  142. package/src/components/Tag/Tag.tsx +35 -19
  143. package/src/components/Tag/variables.dark.ts +135 -36
  144. package/src/components/Tag/variables.ts +78 -61
  145. package/src/core/constants/index.ts +1 -0
  146. package/src/core/constants/mcp.ts +1 -0
  147. package/src/core/constants/search.ts +8 -4
  148. package/src/core/hooks/index.ts +3 -0
  149. package/src/core/hooks/menu/use-nested-menu.ts +2 -2
  150. package/src/core/hooks/search/use-feedback-tooltip.ts +32 -0
  151. package/src/core/hooks/use-connect-mcp-button.ts +79 -0
  152. package/src/core/hooks/use-mcp-config.ts +43 -0
  153. package/src/core/hooks/use-page-actions.ts +148 -126
  154. package/src/core/hooks/use-product-picker.ts +2 -1
  155. package/src/core/hooks/use-tabs.ts +168 -86
  156. package/src/core/hooks/use-telemetry-fallback.ts +10 -8
  157. package/src/core/openapi/index.ts +1 -0
  158. package/src/core/styles/dark.ts +4 -0
  159. package/src/core/styles/global.ts +6 -1
  160. package/src/core/types/hooks.ts +5 -1
  161. package/src/core/types/index.ts +1 -0
  162. package/src/core/types/l10n.ts +13 -0
  163. package/src/core/types/mcp.ts +8 -0
  164. package/src/core/types/search.ts +13 -4
  165. package/src/core/types/segmented.ts +14 -0
  166. package/src/core/utils/frontmatter-translate.ts +9 -0
  167. package/src/core/utils/index.ts +2 -0
  168. package/src/core/utils/mcp.ts +34 -0
  169. package/src/icons/AiStarsGradientIcon/AiStarsGradientIcon.tsx +13 -4
  170. package/src/icons/AiStarsIcon/AiStarsIcon.tsx +11 -2
  171. package/src/icons/ConnectIcon/ConnectIcon.tsx +27 -0
  172. package/src/icons/CubeIcon/CubeIcon.tsx +27 -0
  173. package/src/icons/HashtagIcon/HashtagIcon.tsx +23 -0
  174. package/src/icons/RedoclyIcon/RedoclyIcon.tsx +4 -22
  175. package/src/icons/ThumbDownFilledIcon/ThumbDownFilledIcon.tsx +38 -0
  176. package/src/icons/ThumbUpFilledIcon/ThumbUpFilledIcon.tsx +35 -0
  177. package/src/icons/VSCodeIcon/VSCodeIcon.tsx +29 -0
  178. package/src/index.ts +1 -2
  179. package/src/markdoc/components/Cards/Card.tsx +1 -28
  180. package/src/markdoc/components/ConnectMCP/ConnectMCP.tsx +28 -0
  181. package/src/markdoc/components/Tabs/TabList.tsx +312 -105
  182. package/src/markdoc/components/Tabs/Tabs.tsx +136 -11
  183. package/src/markdoc/components/default.ts +1 -0
  184. package/src/markdoc/default.ts +2 -0
  185. package/src/markdoc/tags/card.ts +0 -1
  186. package/src/markdoc/tags/connect-mcp.ts +25 -0
  187. package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.d.ts +0 -1
  188. package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.js +0 -11
  189. package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.d.ts +0 -1
  190. package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.js +0 -5
  191. package/lib/ext/process-scorecard.d.ts +0 -5
  192. package/lib/ext/process-scorecard.js +0 -11
  193. package/src/components/OpenApiDocs/hooks/AdditionalOverviewInfo.tsx +0 -9
  194. package/src/components/OpenApiDocs/hooks/AfterOpenApiDescription.tsx +0 -1
  195. package/src/ext/process-scorecard.ts +0 -13
@@ -16,6 +16,7 @@ export const tag = css`
16
16
  --tag-badge-border-width: 2px;
17
17
  --tag-badge-border-color: var(--border-color-secondary); // @presenter Color
18
18
  --tag-border-color-focused: var(--color-blue-4); // @presenter Color
19
+ --tag-close-button-bg-color-focus: var(--color-warm-grey-4); // @presenter Color
19
20
 
20
21
  /**
21
22
  * @tokens Tag spacing
@@ -62,6 +63,7 @@ export const tag = css`
62
63
  --tag-icon-width: 14px; // @presenter Spacing
63
64
  --tag-icon-height: 14px; // @presenter Spacing
64
65
 
66
+
65
67
  /**
66
68
  * @tokens Tag colors
67
69
  */
@@ -157,8 +159,7 @@ export const tag = css`
157
159
  --tag-border-color-hover: var(--color-info-border-hover); // @presenter Color
158
160
  }
159
161
 
160
- .tag-purple,
161
- .tag-head {
162
+ .tag-purple {
162
163
  --tag-color: var(--color-purple-7); // @presenter Color
163
164
  --tag-bg-color: var(--color-purple-1); // @presenter Color
164
165
  --tag-border-color: var(--color-purple-4); // @presenter Color
@@ -269,109 +270,125 @@ export const tag = css`
269
270
  * @tokens Operation tag colors
270
271
  */
271
272
 
272
- --tag-operation-color-delete: #e70b46; // @presenter Color
273
- --tag-operation-bg-color-delete: #fee2e9; // @presenter Color
274
-
275
- --tag-operation-color-get: #25b869; // @presenter Color
276
- --tag-operation-bg-color-get: #e5faef; // @presenter Color
277
-
278
- --tag-operation-color-post: #1e65f5; // @presenter Color
279
- --tag-operation-bg-color-post: #e2ebfe; // @presenter Color
280
-
281
- --tag-operation-color-put: #f5901d; // @presenter Color
282
- --tag-operation-bg-color-put: #fef1e2; // @presenter Color
283
-
284
- --tag-operation-color-patch: #f5c31d; // @presenter Color
285
- --tag-operation-bg-color-patch: #fdf6dd; // @presenter Color
286
-
287
- --tag-operation-color-head: #5b4ccc; // @presenter Color
288
- --tag-operation-bg-color-head: #e6e1fe; // @presenter Color
289
-
290
- --tag-operation-color-options: #1a1c21; // @presenter Color
291
- --tag-operation-bg-color-options: #ededf2; // @presenter Color
292
-
293
- --tag-operation-color-deprecated: var(--text-color-disabled); // @presenter Color
294
-
295
- --tag-action-color-receive: #4db144; // @presenter Color
296
- --tag-action-color-sub: #4db144; // @presenter Color
297
- --tag-action-color-cons: #4db144; // @presenter Color
298
-
299
- --tag-action-color-send: #4144f6; // @presenter Color
300
- --tag-action-color-pub: #4144f6; // @presenter Color
301
- --tag-action-color-publish: #4144f6; // @presenter Color
302
-
303
- --tag-action-color-channel: #F0870E; // @presenter Color
304
- --tag-action-color-topic: #F0870E; // @presenter Color
305
- --tag-action-color-queue: #D72E81; // @presenter Color
306
- --tag-action-color-exchange: #9B51E0; // @presenter Color
273
+ .tag-head {
274
+ --tag-color: #6355CA; // @presenter Color
275
+ --tag-bg-color: #ECEBFA; // @presenter Color
276
+ --tag-bg-color-hover: #E0DEF7; // @presenter Color
277
+ }
307
278
 
308
279
  .tag-delete {
309
- --tag-color: var(--tag-operation-color-delete); // @presenter Color
280
+ --tag-color: #e70b46; // @presenter Color
281
+ --tag-bg-color: #fee2e9; // @presenter Color
282
+ --tag-bg-color-hover: #fdd3dd; // @presenter Color
310
283
  }
311
284
 
312
285
  .tag-get {
313
- --tag-color: var(--tag-operation-color-get); // @presenter Color
286
+ --tag-color: #25b869; // @presenter Color
287
+ --tag-bg-color: #e5faef; // @presenter Color
288
+ --tag-bg-color-hover: #D4F7E5; // @presenter Color
314
289
  }
315
290
 
316
291
  .tag-post {
317
- --tag-color: var(--tag-operation-color-post); // @presenter Color
292
+ --tag-color: #1e65f5; // @presenter Color
293
+ --tag-bg-color: #e2ebfe; // @presenter Color
294
+ --tag-bg-color-hover: #CEDDFD; // @presenter Color
318
295
  }
319
296
 
320
297
  .tag-put {
321
- --tag-color: var(--tag-operation-color-put); // @presenter Color
298
+ --tag-color: #f5901d; // @presenter Color
299
+ --tag-bg-color: #fef1e2; // @presenter Color
300
+ --tag-bg-color-hover: #FDE2C4; // @presenter Color
322
301
  }
323
-
302
+
324
303
  .tag-patch {
325
- --tag-color: var(--tag-operation-color-patch); // @presenter Color
304
+ --tag-color: #f5c31d; // @presenter Color
305
+ --tag-bg-color: #fdf6dd; // @presenter Color
306
+ --tag-bg-color-hover: #FCF0C5; // @presenter Color
326
307
  }
327
308
 
328
309
  .tag-http-deprecated {
329
- --tag-color: var(--tag-operation-color-deprecated) // @presenter Color
330
- }
331
-
332
- .tag-receive {
333
- --tag-color: var(--tag-action-color-receive); // @presenter Color
310
+ --tag-color: var(--text-color-disabled); // @presenter Color
334
311
  }
335
312
 
336
313
  .tag-send {
337
- --tag-color: var(--tag-action-color-send); // @presenter Color
314
+ --tag-color: #4144F6; // @presenter Color
315
+ --tag-bg-color: #ECECFE; // @presenter Color
316
+ --tag-bg-color-hover: #CFCFFC; // @presenter Color
338
317
  }
339
318
 
340
319
  .tag-pub {
341
- --tag-color: var(--tag-action-color-pub); // @presenter Color
320
+ --tag-color: #4144F6; // @presenter Color
321
+ --tag-bg-color: #ECECFE; // @presenter Color
322
+ --tag-bg-color-hover: #CFCFFC; // @presenter Color
342
323
  }
343
324
 
344
- .tag-sub {
345
- --tag-color: var(--tag-action-color-sub); // @presenter Color
325
+ .tag-publish {
326
+ --tag-color: #4144F6; // @presenter Color
327
+ --tag-bg-color: #ECECFE; // @presenter Color
328
+ --tag-bg-color-hover: #CFCFFC; // @presenter Color
346
329
  }
347
330
 
348
- .tag-cons {
349
- --tag-color: var(--tag-action-color-cons); // @presenter Color
331
+ .tag-receive {
332
+ --tag-color: #4db144; // @presenter Color
333
+ --tag-bg-color: #E5FDE2; // @presenter Color
334
+ --tag-bg-color-hover: #D4FCCF; // @presenter Color
350
335
  }
351
336
 
352
- .tag-publish {
353
- --tag-color: var(--tag-action-color-publish); // @presenter Color
337
+ .tag-sub {
338
+ --tag-color: #4db144; // @presenter Color
339
+ --tag-bg-color: #E5FDE2; // @presenter Color
340
+ --tag-bg-color-hover: #D4FCCF; // @presenter Color
341
+ }
342
+
343
+ .tag-cons {
344
+ --tag-color: #4db144; // @presenter Color
345
+ --tag-bg-color: #E5FDE2; // @presenter Color
346
+ --tag-bg-color-hover: #D4FCCF; // @presenter Color
354
347
  }
355
348
 
356
349
  .tag-channel {
357
- --tag-color: var(--tag-action-color-channel); // @presenter Color
350
+ --tag-color: #F0870E; // @presenter Color
351
+ --tag-bg-color: #FDF1E2; // @presenter Color
352
+ --tag-bg-color-hover: #FBE1C1; // @presenter Color
358
353
  }
359
354
 
360
355
  .tag-topic {
361
- --tag-color: var(--tag-action-color-channel); // @presenter Color
356
+ --tag-color: #F0870E; // @presenter Color
357
+ --tag-bg-color: #FDF1E2; // @presenter Color
358
+ --tag-bg-color-hover: #FBE1C1; // @presenter Color
362
359
  }
363
360
 
364
361
  .tag-queue {
365
- --tag-color: var(--tag-action-color-queue); // @presenter Color
362
+ --tag-color: #D72E81; // @presenter Color
363
+ --tag-bg-color: #FAE5F0; // @presenter Color
364
+ --tag-bg-color-hover: #F7D4E6; // @presenter Color
366
365
  }
367
366
 
368
367
  .tag-exchange {
369
- --tag-color: var(--tag-action-color-exchange); // @presenter Color
368
+ --tag-color: #9B51E0; // @presenter Color
369
+ --tag-bg-color: #F0E5FA; // @presenter Color
370
+ --tag-bg-color-hover: #E6D4F7; // @presenter Color
370
371
  }
371
372
 
372
373
  // shorten alias for exchange tag:
373
374
  .tag-exch {
374
- --tag-color: var(--tag-action-color-exchange); // @presenter Color
375
+ --tag-color: #9B51E0; // @presenter Color
376
+ --tag-bg-color: #F0E5FA; // @presenter Color
377
+ --tag-bg-color-hover: #E6D4F7; // @presenter Color
378
+ }
379
+
380
+ /**
381
+ * @tokens Tag variants
382
+ */
383
+
384
+ .tag-variant-filled {
385
+ --tag-border-color: transparent;
386
+ --tag-border-color-hover: transparent;
387
+ }
388
+
389
+ .tag-variant-outline {
390
+ --tag-bg-color: transparent;
391
+ --tag-bg-color-hover: transparent;
375
392
  }
376
393
 
377
394
  // @tokens End
@@ -4,3 +4,4 @@ export * from './code-walkthrough';
4
4
  export * from './search';
5
5
  export * from './catalog';
6
6
  export * from './breadcrumb';
7
+ export * from './mcp';
@@ -0,0 +1 @@
1
+ export const DEFAULT_MCP_SERVER_NAME = 'mcp-server';
@@ -7,10 +7,14 @@ export enum AiSearchError {
7
7
  EmptyResponse = 'empty_response',
8
8
  ErrorProcessingResponse = 'error_processing_response',
9
9
  }
10
- export const enum AiSearchConversationRole {
11
- USER = 'user',
12
- ASSISTANT = 'assistant',
13
- }
10
+
11
+ export const AiSearchConversationRole = {
12
+ USER: 'user',
13
+ ASSISTANT: 'assistant',
14
+ } as const;
15
+
16
+ export type AiSearchConversationRole =
17
+ (typeof AiSearchConversationRole)[keyof typeof AiSearchConversationRole];
14
18
 
15
19
  const defaultErrorConfig: AiSearchErrorConfig = {
16
20
  headerKey: 'search.ai.error.header',
@@ -26,6 +26,7 @@ export * from './use-language-picker';
26
26
  export * from './use-product-picker';
27
27
  export * from './search/use-search-dialog';
28
28
  export * from './search/use-search-filter';
29
+ export * from './search/use-feedback-tooltip';
29
30
  export * from './use-controlled-state';
30
31
  export * from './use-codeblock-tabs-controls';
31
32
  export * from './code-walkthrough/use-code-walkthrough';
@@ -42,3 +43,5 @@ export * from './use-active-page-version';
42
43
  export * from './use-page-versions';
43
44
  export * from './use-user-teams';
44
45
  export * from './use-page-actions';
46
+ export * from './use-mcp-config';
47
+ export * from './use-connect-mcp-button';
@@ -6,7 +6,7 @@ import type { MenuItemProps } from '../../types/sidebar';
6
6
  import { useMenuItemExpanded } from './use-menu-item-expanded';
7
7
  import { useCollapse } from './use-collapse';
8
8
  import { loadAndNavigate } from '../../utils/load-and-navigate';
9
- import { withoutPathPrefix } from '../../utils/urls';
9
+ import { withoutPathPrefix, withPathPrefix } from '../../utils/urls';
10
10
 
11
11
  type NestedMenuProps = MenuItemProps & {
12
12
  labelRef?: React.RefObject<HTMLElement | null>;
@@ -78,7 +78,7 @@ export function useNestedMenu({ item, labelRef, nestedMenuRef }: NestedMenuProps
78
78
 
79
79
  const [firstChild] = item.items;
80
80
  if (!isExpanded && item.selectFirstItemOnExpand && firstChild.link) {
81
- await loadAndNavigate({ navigate, to: firstChild.link });
81
+ await loadAndNavigate({ navigate, to: withPathPrefix(firstChild.link) });
82
82
  }
83
83
  setIsExpanded(!isExpanded);
84
84
  }, [item, isExpanded, navigate, location.pathname, setIsExpanded]);
@@ -0,0 +1,32 @@
1
+ import { useState } from 'react';
2
+
3
+ import { useControl } from '../use-control';
4
+
5
+ type UseFeedbackTooltipReturn = {
6
+ isOpen: boolean;
7
+ showTooltip: () => void;
8
+ };
9
+
10
+ const DEFAULT_TOOLTIP_DURATION = 1500;
11
+
12
+ export function useFeedbackTooltip(): UseFeedbackTooltipReturn {
13
+ const [closeTooltipTimeout, setCloseTooltipTimeout] = useState<NodeJS.Timeout | null>(null);
14
+ const tooltipControl = useControl();
15
+
16
+ const showTooltip = () => {
17
+ tooltipControl.handleOpen();
18
+ if (closeTooltipTimeout) {
19
+ clearTimeout(closeTooltipTimeout);
20
+ }
21
+ const newCloseTooltipTimeout = setTimeout(() => {
22
+ tooltipControl.handleClose();
23
+ setCloseTooltipTimeout(null);
24
+ }, DEFAULT_TOOLTIP_DURATION);
25
+ setCloseTooltipTimeout(newCloseTooltipTimeout);
26
+ };
27
+
28
+ return {
29
+ isOpen: tooltipControl.isOpened,
30
+ showTooltip,
31
+ };
32
+ }
@@ -0,0 +1,79 @@
1
+ import { useState, useCallback, useMemo } from 'react';
2
+ import debounce from 'lodash.debounce';
3
+
4
+ import type { MCPOption } from '../types';
5
+
6
+ import { useThemeHooks } from './use-theme-hooks';
7
+ import { useMCPConfig } from './use-mcp-config';
8
+ import { ClipboardService } from '../utils/clipboard-service';
9
+
10
+ export type McpButtonOptions = {
11
+ options?: MCPOption[];
12
+ };
13
+
14
+ export type McpButtonSettings = {
15
+ isCopied: boolean;
16
+ cursorUrl: string;
17
+ vscodeUrl: string;
18
+ triggerButtonText: string;
19
+ visibleOptions: MCPOption[];
20
+ handleAction: (action: MCPOption) => void;
21
+ };
22
+
23
+ const COPIED_RESET_TIMEOUT = 1000;
24
+
25
+ export function useConnectMCPButton({
26
+ options = ['cursor', 'vscode', 'copy'],
27
+ }: McpButtonOptions = {}): McpButtonSettings {
28
+ const { useTranslate } = useThemeHooks();
29
+ const { translate } = useTranslate();
30
+ const { serverName, serverUrl, cursorUrl, vscodeUrl } = useMCPConfig();
31
+ const [isCopied, setIsCopied] = useState(false);
32
+
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ const resetCopied = useCallback(
35
+ debounce(() => setIsCopied(false), COPIED_RESET_TIMEOUT),
36
+ [],
37
+ );
38
+
39
+ const handleAction = useCallback(
40
+ (action: MCPOption) => {
41
+ if (action === 'copy') {
42
+ const config = {
43
+ [serverName]: {
44
+ url: serverUrl,
45
+ description: 'MCP Server',
46
+ },
47
+ };
48
+ ClipboardService.copyCustom(JSON.stringify(config, null, 2));
49
+ setIsCopied(true);
50
+ resetCopied();
51
+ return;
52
+ }
53
+
54
+ const urlMap: Record<Exclude<MCPOption, 'copy'>, string> = {
55
+ cursor: cursorUrl,
56
+ vscode: vscodeUrl,
57
+ };
58
+
59
+ window.open(urlMap[action], '_blank');
60
+ },
61
+ [cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied],
62
+ );
63
+
64
+ const triggerButtonText = useMemo(
65
+ () => translate('page.actions.connectMcp', 'Connect MCP'),
66
+ [translate],
67
+ );
68
+
69
+ const visibleOptions = useMemo(() => options.filter(Boolean), [options]);
70
+
71
+ return {
72
+ isCopied,
73
+ cursorUrl,
74
+ vscodeUrl,
75
+ triggerButtonText,
76
+ visibleOptions,
77
+ handleAction,
78
+ };
79
+ }
@@ -0,0 +1,43 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { useThemeConfig } from './use-theme-config';
4
+ import { IS_BROWSER } from '../utils/dom';
5
+ import { DEFAULT_MCP_SERVER_NAME } from '../constants';
6
+ import { generateMCPDeepLink } from '../utils/mcp';
7
+
8
+ export type McpConfig = {
9
+ serverName: string;
10
+ origin: string;
11
+ serverUrl: string;
12
+ cursorUrl: string;
13
+ vscodeUrl: string;
14
+ isMcpDisabled: boolean;
15
+ };
16
+
17
+ export function useMCPConfig(): McpConfig {
18
+ const themeConfig = useThemeConfig();
19
+
20
+ const origin = IS_BROWSER ? window.location.origin : (globalThis as any)['SSR_HOSTNAME'];
21
+ const serverName = themeConfig.mcp?.docs?.name || DEFAULT_MCP_SERVER_NAME;
22
+ const serverUrl = `${origin}/mcp`;
23
+ const isMcpDisabled = themeConfig.mcp?.hide || themeConfig.mcp?.docs?.hide || false;
24
+
25
+ const cursorUrl = useMemo(
26
+ () => generateMCPDeepLink('cursor', { serverName, url: serverUrl }),
27
+ [serverName, serverUrl],
28
+ );
29
+
30
+ const vscodeUrl = useMemo(
31
+ () => generateMCPDeepLink('vscode', { serverName, url: serverUrl }),
32
+ [serverName, serverUrl],
33
+ );
34
+
35
+ return {
36
+ serverName,
37
+ origin,
38
+ serverUrl,
39
+ cursorUrl,
40
+ vscodeUrl,
41
+ isMcpDisabled,
42
+ };
43
+ }