@redocly/theme 0.71.0-next.5 → 0.71.0-next.6

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 (61) hide show
  1. package/lib/components/Feedback/Mood.js +1 -1
  2. package/lib/components/Feedback/Rating.js +1 -1
  3. package/lib/components/Feedback/Scale.js +1 -1
  4. package/lib/components/Feedback/Sentiment.js +1 -1
  5. package/lib/components/Filter/Filter.js +1 -1
  6. package/lib/components/MCP/McpConnectionTabs.d.ts +1 -1
  7. package/lib/components/MCP/McpConnectionTabs.js +24 -1
  8. package/lib/components/MissingTranslationNotice/MissingTranslationNotice.d.ts +11 -0
  9. package/lib/components/MissingTranslationNotice/MissingTranslationNotice.js +83 -0
  10. package/lib/components/MissingTranslationNotice/variables.d.ts +1 -0
  11. package/lib/components/MissingTranslationNotice/variables.dark.d.ts +1 -0
  12. package/lib/components/MissingTranslationNotice/variables.dark.js +10 -0
  13. package/lib/components/MissingTranslationNotice/variables.js +29 -0
  14. package/lib/components/PageActions/PageActions.js +1 -0
  15. package/lib/components/Select/Select.js +1 -2
  16. package/lib/core/hooks/use-active-section-id.js +8 -0
  17. package/lib/core/hooks/use-page-actions.d.ts +1 -1
  18. package/lib/core/hooks/use-page-actions.js +18 -2
  19. package/lib/core/styles/dark.js +4 -2
  20. package/lib/core/styles/global.js +70 -68
  21. package/lib/core/types/hooks.d.ts +2 -5
  22. package/lib/core/types/l10n.d.ts +2 -1
  23. package/lib/core/utils/mcp.d.ts +1 -0
  24. package/lib/core/utils/mcp.js +4 -0
  25. package/lib/icons/McpIcon/McpIcon.d.ts +25 -0
  26. package/lib/icons/McpIcon/McpIcon.js +24 -0
  27. package/lib/icons/TranslateIcon/TranslateIcon.d.ts +25 -0
  28. package/lib/icons/TranslateIcon/TranslateIcon.js +21 -0
  29. package/lib/index.d.ts +2 -0
  30. package/lib/index.js +3 -0
  31. package/lib/layouts/CodeWalkthroughLayout.js +9 -1
  32. package/lib/layouts/DocumentationLayout.js +2 -0
  33. package/package.json +3 -3
  34. package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +1 -1
  35. package/src/components/Feedback/Mood.tsx +1 -1
  36. package/src/components/Feedback/Rating.tsx +1 -1
  37. package/src/components/Feedback/Scale.tsx +1 -1
  38. package/src/components/Feedback/Sentiment.tsx +1 -1
  39. package/src/components/Filter/Filter.tsx +2 -2
  40. package/src/components/MCP/McpConnectionTabs.tsx +56 -2
  41. package/src/components/MissingTranslationNotice/MissingTranslationNotice.tsx +113 -0
  42. package/src/components/MissingTranslationNotice/variables.dark.ts +7 -0
  43. package/src/components/MissingTranslationNotice/variables.ts +26 -0
  44. package/src/components/PageActions/PageActions.tsx +1 -0
  45. package/src/components/Search/FilterFields/SearchFilterFieldSelect.tsx +1 -1
  46. package/src/components/Select/Select.tsx +1 -2
  47. package/src/core/hooks/__mocks__/use-theme-hooks.ts +1 -1
  48. package/src/core/hooks/use-active-section-id.ts +13 -0
  49. package/src/core/hooks/use-codeblock-tabs-controls.ts +1 -1
  50. package/src/core/hooks/use-page-actions.ts +27 -4
  51. package/src/core/styles/dark.ts +2 -0
  52. package/src/core/styles/global.ts +2 -0
  53. package/src/core/types/hooks.ts +2 -2
  54. package/src/core/types/l10n.ts +12 -2
  55. package/src/core/utils/mcp.ts +4 -0
  56. package/src/icons/McpIcon/McpIcon.tsx +37 -0
  57. package/src/icons/TranslateIcon/TranslateIcon.tsx +22 -0
  58. package/src/index.ts +3 -0
  59. package/src/layouts/CodeWalkthroughLayout.tsx +11 -1
  60. package/src/layouts/DocumentationLayout.tsx +2 -0
  61. package/src/markdoc/tags/code-walkthrough.ts +1 -1
@@ -118,8 +118,8 @@ function Mood({ settings, onSubmit, className }) {
118
118
  const hasOptionalEmail = !(optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.hide) && !(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated);
119
119
  const displayReasons = checkIfShouldDisplayReasons(score);
120
120
  const displayComment = !!score && hasComment;
121
- const displaySubmitBnt = !!(score && (displayReasons || displayComment));
122
121
  const displayFeedbackEmail = !!score && hasOptionalEmail;
122
+ const displaySubmitBnt = !!score && (displayReasons || displayComment || displayFeedbackEmail);
123
123
  const submitMood = (moodScore) => {
124
124
  const trimmedComment = (comment === null || comment === void 0 ? void 0 : comment.trim()) || undefined;
125
125
  const trimmedEmail = (email === null || email === void 0 ? void 0 : email.trim()) || undefined;
@@ -94,8 +94,8 @@ function Rating({ settings, onSubmit, className }) {
94
94
  };
95
95
  const displayReasons = !!score && hasReasons;
96
96
  const displayComment = !!score && hasComment;
97
- const displaySubmitBnt = !!(score && (displayReasons || displayComment));
98
97
  const displayFeedbackEmail = !!score && hasOptionalEmail;
98
+ const displaySubmitBnt = !!score && (displayReasons || displayComment || displayFeedbackEmail);
99
99
  if (isSubmitted) {
100
100
  return (React.createElement(RatingWrapper, { "data-component-name": "Feedback/Rating" },
101
101
  React.createElement(StyledFormMandatoryFields, null,
@@ -98,8 +98,8 @@ function Scale({ settings, onSubmit, className }) {
98
98
  }
99
99
  const displayReasons = !!score && hasReasons;
100
100
  const displayComment = !!score && hasComment;
101
- const displaySubmitBnt = !!score && (displayReasons || displayComment);
102
101
  const displayFeedbackEmail = !!score && hasOptionalEmail;
102
+ const displaySubmitBnt = !!score && (displayReasons || displayComment || displayFeedbackEmail);
103
103
  if (isSubmitted) {
104
104
  return (React.createElement(ScaleWrapper, { "data-component-name": "Feedback/Scale" },
105
105
  React.createElement(Label, { "data-translation-key": "feedback.settings.submitText" }, submitText ||
@@ -85,8 +85,8 @@ function Sentiment({ settings, onSubmit, className }) {
85
85
  const hasOptionalEmail = !(optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.hide) && !(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated);
86
86
  const displayReasons = checkIfShouldDisplayReasons(score);
87
87
  const displayComment = !!score && hasComment;
88
- const displaySubmitBnt = !!(score && (displayReasons || displayComment));
89
88
  const displayFeedbackEmail = !!score && hasOptionalEmail;
89
+ const displaySubmitBnt = !!score && (displayReasons || displayComment || displayFeedbackEmail);
90
90
  const commentLabel = score === 1
91
91
  ? (commentSettings && commentSettings.likeLabel) ||
92
92
  translate('feedback.settings.comment.likeLabel', 'What was most helpful?')
@@ -17,7 +17,7 @@ const filterComponents = {
17
17
  function Filter({ filter, filterValuesCasing, showCounter = true, }) {
18
18
  if (!filter.parentUsed)
19
19
  return null;
20
- const FilterComponent = filterComponents[(filter.type || 'checkboxes')];
20
+ const FilterComponent = filterComponents[filter.type || 'checkboxes'];
21
21
  return (react_1.default.createElement(FilterGroup, { "data-component-name": "Filter/Filter", key: filter.property + filter.title },
22
22
  react_1.default.createElement(FilterComponent, { filter: filter, filterValuesCasing: filterValuesCasing, showCounter: showCounter })));
23
23
  }
@@ -1,5 +1,5 @@
1
1
  import type { JSX } from 'react';
2
- export type McpConnectionTab = 'claude' | 'chatgpt' | 'json';
2
+ export type McpConnectionTab = 'claude' | 'chatgpt' | 'grok' | 'json';
3
3
  export type McpConnectionTabsProps = {
4
4
  options?: McpConnectionTab[];
5
5
  className?: string;
@@ -45,11 +45,12 @@ const Button_1 = require("../../components/Button/Button");
45
45
  const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
46
46
  const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
47
47
  const ChatGptIcon_1 = require("../../icons/ChatGptIcon/ChatGptIcon");
48
+ const GrokIcon_1 = require("../../icons/GrokIcon/GrokIcon");
48
49
  const Tabs_1 = require("../../markdoc/components/Tabs/Tabs");
49
50
  const TabItemFragment_1 = require("../../markdoc/components/Tabs/TabItemFragment");
50
51
  const NumberedList_1 = require("../../markdoc/components/NumberedList/NumberedList");
51
52
  const NumberedItem_1 = require("../../markdoc/components/NumberedList/NumberedItem");
52
- const DEFAULT_TAB_OPTIONS = ['claude', 'chatgpt', 'json'];
53
+ const DEFAULT_TAB_OPTIONS = ['claude', 'chatgpt', 'grok', 'json'];
53
54
  const TAB_LABELS = {
54
55
  claude: {
55
56
  translationKey: 'page.mcpNotAllowed.tabs.claude',
@@ -61,8 +62,14 @@ const TAB_LABELS = {
61
62
  defaultLabel: 'ChatGPT',
62
63
  icon: ChatGptIcon_1.ChatGptIcon,
63
64
  },
65
+ grok: {
66
+ translationKey: 'page.mcpNotAllowed.tabs.grok',
67
+ defaultLabel: 'Grok',
68
+ icon: GrokIcon_1.GrokIcon,
69
+ },
64
70
  json: { translationKey: 'page.mcpNotAllowed.tabs.json', defaultLabel: 'JSON' },
65
71
  };
72
+ const GROK_CONNECTORS_URL = 'https://grok.com/connectors';
66
73
  function McpConnectionTabs({ options = DEFAULT_TAB_OPTIONS, className, }) {
67
74
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
68
75
  const { translate } = useTranslate();
@@ -136,6 +143,22 @@ function renderTabContent(option, connection, translate, snippetHeader) {
136
143
  },
137
144
  assistantPromptClient,
138
145
  ]);
146
+ case 'grok':
147
+ return renderClientList([
148
+ {
149
+ headline: translate('page.mcpNotAllowed.snippets.grokBuild.headline', 'Grok Build'),
150
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
151
+ terminalHint,
152
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "shell", source: (0, utils_1.generateGrokBuildCommand)(connection), header: snippetHeader(option, 'grok-build'), wrapContents: true }))),
153
+ },
154
+ {
155
+ headline: translate('page.mcpNotAllowed.snippets.grokApp.headline', 'Grok app'),
156
+ content: (react_1.default.createElement(react_1.default.Fragment, null,
157
+ react_1.default.createElement(ConnectButton, { variant: "secondary", icon: react_1.default.createElement(GrokIcon_1.GrokIcon, null), onClick: () => window.open(GROK_CONNECTORS_URL, '_blank') }, translate('page.mcpNotAllowed.snippets.grokApp.openConnectors', 'Open Grok connectors')),
158
+ react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.grokApp.instruction', 'On grok.com, open Connectors → New Connector → Custom and paste this server URL:')),
159
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "text", source: connection.url, header: snippetHeader(option, 'grok-app') }))),
160
+ },
161
+ ]);
139
162
  case 'json':
140
163
  return (react_1.default.createElement(react_1.default.Fragment, null,
141
164
  react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.json.hint', 'Add this server entry to your MCP client configuration file:')),
@@ -0,0 +1,11 @@
1
+ import type { JSX } from 'react';
2
+ export type MissingTranslationNoticeProps = {
3
+ className?: string;
4
+ };
5
+ /**
6
+ * Tells the reader that the page shows the original language,
7
+ * because the translation for the selected locale is missing.
8
+ * Renders only on fallback pages of a locale that sets `showMissingTranslationNotice`.
9
+ * The reader can close the notice for the current page.
10
+ */
11
+ export declare function MissingTranslationNotice({ className, }: MissingTranslationNoticeProps): JSX.Element | null;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MissingTranslationNotice = MissingTranslationNotice;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const CloseIcon_1 = require("../../icons/CloseIcon/CloseIcon");
10
+ const TranslateIcon_1 = require("../../icons/TranslateIcon/TranslateIcon");
11
+ const Markdown_1 = require("../../components/Markdown/Markdown");
12
+ const hooks_1 = require("../../core/hooks");
13
+ /**
14
+ * Tells the reader that the page shows the original language,
15
+ * because the translation for the selected locale is missing.
16
+ * Renders only on fallback pages of a locale that sets `showMissingTranslationNotice`.
17
+ * The reader can close the notice for the current page.
18
+ */
19
+ function MissingTranslationNotice({ className, }) {
20
+ var _a;
21
+ const { useTranslate, useMarkdownText, usePageProps, useL10nConfig } = (0, hooks_1.useThemeHooks)();
22
+ const { translate } = useTranslate();
23
+ const { isTranslationFallback } = usePageProps();
24
+ const { currentLocale, defaultLocale, locales } = useL10nConfig();
25
+ const [isDismissed, setIsDismissed] = react_1.default.useState(false);
26
+ const isShown = isTranslationFallback === true &&
27
+ currentLocale !== defaultLocale &&
28
+ locales.some(({ code, showMissingTranslationNotice }) => code === currentLocale && showMissingTranslationNotice === true);
29
+ const language = ((_a = locales.find(({ code }) => code === defaultLocale)) === null || _a === void 0 ? void 0 : _a.name) || defaultLocale;
30
+ const content = useMarkdownText(isShown ? translate('missingTranslationNotice.content', { language }) : '');
31
+ if (!isShown || isDismissed) {
32
+ return null;
33
+ }
34
+ return (react_1.default.createElement(MissingTranslationNoticeWrapper, { className: className, "data-component-name": "MissingTranslationNotice/MissingTranslationNotice" },
35
+ react_1.default.createElement(Icon, { color: "--missing-translation-notice-icon-color" }),
36
+ react_1.default.createElement(Content, null,
37
+ react_1.default.createElement(Title, null, translate('missingTranslationNotice.title', {
38
+ defaultValue: 'This page has not yet been translated',
39
+ })),
40
+ react_1.default.createElement(Markdown_1.Markdown, { compact: true }, content)),
41
+ react_1.default.createElement(CloseButton, { type: "button", "aria-label": translate('missingTranslationNotice.close', { defaultValue: 'Close' }), onClick: () => setIsDismissed(true) },
42
+ react_1.default.createElement(CloseIcon_1.CloseIcon, { color: "--missing-translation-notice-text-color" }))));
43
+ }
44
+ const MissingTranslationNoticeWrapper = styled_components_1.default.div `
45
+ display: flex;
46
+ flex-direction: row;
47
+ align-items: flex-start;
48
+ gap: var(--missing-translation-notice-gap);
49
+
50
+ padding: var(--missing-translation-notice-padding);
51
+ margin: var(--missing-translation-notice-margin-vertical) 0;
52
+ color: var(--missing-translation-notice-text-color);
53
+ background-color: var(--missing-translation-notice-bg-color);
54
+ border: 1px solid var(--missing-translation-notice-border-color);
55
+ border-left: var(--missing-translation-notice-accent-width) solid
56
+ var(--missing-translation-notice-accent-color);
57
+ border-radius: var(--missing-translation-notice-border-radius);
58
+ `;
59
+ const Icon = (0, styled_components_1.default)(TranslateIcon_1.TranslateIcon) `
60
+ flex-shrink: 0;
61
+ `;
62
+ const Content = styled_components_1.default.div `
63
+ display: flex;
64
+ flex-direction: column;
65
+ flex: 1;
66
+ gap: var(--spacing-xxs);
67
+
68
+ font-size: var(--missing-translation-notice-font-size);
69
+ line-height: var(--missing-translation-notice-line-height);
70
+ `;
71
+ const Title = styled_components_1.default.span `
72
+ font-size: var(--missing-translation-notice-title-font-size);
73
+ font-weight: var(--missing-translation-notice-title-font-weight);
74
+ `;
75
+ const CloseButton = styled_components_1.default.button `
76
+ display: flex;
77
+ flex-shrink: 0;
78
+ padding: 0;
79
+ border: none;
80
+ background: none;
81
+ cursor: pointer;
82
+ `;
83
+ //# sourceMappingURL=MissingTranslationNotice.js.map
@@ -0,0 +1 @@
1
+ export declare const missingTranslationNotice: import("styled-components").RuleSet<object>;
@@ -0,0 +1 @@
1
+ export declare const missingTranslationNoticeDarkMode: import("styled-components").RuleSet<object>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.missingTranslationNoticeDarkMode = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.missingTranslationNoticeDarkMode = (0, styled_components_1.css) `
6
+ --missing-translation-notice-bg-color: var(--color-warm-grey-3); // @presenter Color
7
+ --missing-translation-notice-icon-color: var(--color-blue-4); // @presenter Color
8
+ --missing-translation-notice-accent-color: var(--color-blue-4); // @presenter Color
9
+ `;
10
+ //# sourceMappingURL=variables.dark.js.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.missingTranslationNotice = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.missingTranslationNotice = (0, styled_components_1.css) `
6
+ /**
7
+ * @tokens Missing translation notice
8
+ */
9
+
10
+ --missing-translation-notice-bg-color: var(--color-warm-grey-1); // @presenter Color
11
+ --missing-translation-notice-text-color: var(--text-color-primary); // @presenter Color
12
+ --missing-translation-notice-icon-color: var(--color-blue-6); // @presenter Color
13
+ --missing-translation-notice-border-color: var(--border-color-secondary); // @presenter Color
14
+ --missing-translation-notice-accent-color: var(--color-blue-6); // @presenter Color
15
+
16
+ --missing-translation-notice-accent-width: 3px; // @presenter Spacing
17
+ --missing-translation-notice-border-radius: var(--border-radius-lg); // @presenter BorderRadius
18
+ --missing-translation-notice-padding: var(--spacing-sm) var(--spacing-base); // @presenter Spacing
19
+ --missing-translation-notice-margin-vertical: var(--spacing-base); // @presenter Spacing
20
+ --missing-translation-notice-gap: var(--spacing-sm); // @presenter Spacing
21
+
22
+ --missing-translation-notice-title-font-size: var(--font-size-base); // @presenter FontSize
23
+ --missing-translation-notice-title-font-weight: var(--font-weight-semibold); // @presenter FontWeight
24
+ --missing-translation-notice-font-size: var(--font-size-base); // @presenter FontSize
25
+ --missing-translation-notice-line-height: var(--line-height-base); // @presenter LineHeight
26
+
27
+ // @tokens End
28
+ `;
29
+ //# sourceMappingURL=variables.js.map
@@ -102,6 +102,7 @@ function renderIcon(buttonAction, actionState) {
102
102
  const PageActionsWrapper = styled_components_1.default.div `
103
103
  margin-left: auto;
104
104
  padding-left: var(--page-actions-padding-left);
105
+ user-select: none;
105
106
  --button-color: var(--page-actions-button-text-color);
106
107
 
107
108
  .button-group-size-medium .button.button-size-medium {
@@ -55,8 +55,7 @@ function Select(props) {
55
55
  return values
56
56
  .map((value) => {
57
57
  const selectedOption = options.find((option) => option.value === value);
58
- return (selectedOption ||
59
- (typeof value === 'string' ? { value } : value));
58
+ return (selectedOption || (typeof value === 'string' ? { value } : value));
60
59
  })
61
60
  .filter((option) => !!option);
62
61
  };
@@ -46,7 +46,14 @@ function useActiveSectionId(location, hasOverviewPage = false, withNavbar = true
46
46
  if (!dom_1.IS_BROWSER) {
47
47
  return;
48
48
  }
49
+ // A one-event scroll jump is read before the section it lands on stops being skipped.
50
+ const onContentVisibilityChange = (event) => {
51
+ if ('skipped' in event && event.skipped === false) {
52
+ scrollListener();
53
+ }
54
+ };
49
55
  window.addEventListener('scroll', scrollListener, { capture: false });
56
+ window.addEventListener('contentvisibilityautostatechange', onContentVisibilityChange, true);
50
57
  const initialRead = setTimeout(() => {
51
58
  scrollListener();
52
59
  }, 10);
@@ -54,6 +61,7 @@ function useActiveSectionId(location, hasOverviewPage = false, withNavbar = true
54
61
  clearTimeout(initialRead);
55
62
  scrollListener.cancel();
56
63
  window.removeEventListener('scroll', scrollListener);
64
+ window.removeEventListener('contentvisibilityautostatechange', onContentVisibilityChange, true);
57
65
  };
58
66
  }, [location, heightOffset, scrollListener]);
59
67
  return itemId;
@@ -1,3 +1,3 @@
1
1
  import type { PageAction } from '../types';
2
- export type PageActionType = 'copy' | 'view' | 'chatgpt' | 'claude' | 'grok' | 'docs-mcp-cursor' | 'docs-mcp-vscode' | 'docs-mcp-claude' | 'mcp-cursor' | 'mcp-vscode';
2
+ export type PageActionType = 'copy' | 'view' | 'chatgpt' | 'claude' | 'grok' | 'docs-mcp-claude' | 'docs-mcp-vscode' | 'docs-mcp-cursor' | 'copy-mcp-url' | 'mcp-cursor' | 'mcp-vscode';
3
3
  export declare function usePageActions(pageSlug: string, mcpUrl?: string, actions?: PageActionType[]): PageAction[];
@@ -15,6 +15,7 @@ const CopyIcon_1 = require("../../icons/CopyIcon/CopyIcon");
15
15
  const ChatGptIcon_1 = require("../../icons/ChatGptIcon/ChatGptIcon");
16
16
  const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
17
17
  const GrokIcon_1 = require("../../icons/GrokIcon/GrokIcon");
18
+ const McpIcon_1 = require("../../icons/McpIcon/McpIcon");
18
19
  const MarkdownFullIcon_1 = require("../../icons/MarkdownFullIcon/MarkdownFullIcon");
19
20
  const VSCodeIcon_1 = require("../../icons/VSCodeIcon/VSCodeIcon");
20
21
  const CursorIcon_1 = require("../../icons/CursorIcon/CursorIcon");
@@ -33,9 +34,10 @@ const DEFAULT_ENABLED_ACTIONS = [
33
34
  'chatgpt',
34
35
  'claude',
35
36
  'grok',
36
- 'docs-mcp-cursor',
37
- 'docs-mcp-vscode',
38
37
  'docs-mcp-claude',
38
+ 'docs-mcp-vscode',
39
+ 'docs-mcp-cursor',
40
+ 'copy-mcp-url',
39
41
  ];
40
42
  function usePageActions(pageSlug, mcpUrl, actions) {
41
43
  var _a;
@@ -100,6 +102,18 @@ function usePageActions(pageSlug, mcpUrl, actions) {
100
102
  'docs-mcp-cursor': createMCPHandler('cursor', false),
101
103
  'docs-mcp-vscode': createMCPHandler('vscode', false),
102
104
  'docs-mcp-claude': createMCPHandler('claude', false),
105
+ 'copy-mcp-url': () => ({
106
+ buttonText: translate('page.actions.connectMcp.copyUrl', 'Copy MCP server URL'),
107
+ title: translate('page.actions.connectMcp.copyUrl', 'Copy MCP server URL'),
108
+ description: translate('page.actions.connectMcp.copyUrlDescription', 'Copy the MCP server URL to the clipboard'),
109
+ iconComponent: McpIcon_1.McpIcon,
110
+ onClick: () => {
111
+ clipboard_service_1.ClipboardService.copyCustom(mcpConfig.serverUrl);
112
+ telemetry.sendPageActionsClickedMessage([
113
+ Object.assign(Object.assign({}, (0, get_base_data_attributes_1.getBaseDataAttributes)('pageActions', 'button')), { actionType: 'copy-mcp-url' }),
114
+ ]);
115
+ },
116
+ }),
103
117
  'mcp-cursor': createMCPHandler('cursor', true),
104
118
  'mcp-vscode': createMCPHandler('vscode', true),
105
119
  copy: () => ({
@@ -163,6 +177,7 @@ function usePageActions(pageSlug, mcpUrl, actions) {
163
177
  isPublic,
164
178
  mcpUrl,
165
179
  mcpConfig.isMcpDisabled,
180
+ mcpConfig.serverUrl,
166
181
  pageSlug,
167
182
  actions,
168
183
  translate,
@@ -219,6 +234,7 @@ function shouldHideActionByType(action, { isPublic, mcpUrl, isMcpDisabled, }) {
219
234
  case 'docs-mcp-cursor':
220
235
  case 'docs-mcp-vscode':
221
236
  case 'docs-mcp-claude':
237
+ case 'copy-mcp-url':
222
238
  return Boolean(mcpUrl) || isMcpDisabled;
223
239
  case 'mcp-cursor':
224
240
  case 'mcp-vscode':
@@ -18,7 +18,8 @@ const variables_dark_13 = require("../../components/PageActions/variables.dark")
18
18
  const variables_dark_14 = require("../../components/Tooltip/variables.dark");
19
19
  const variables_dark_15 = require("../../components/Banner/variables.dark");
20
20
  const variables_dark_16 = require("../../components/Admonition/variables.dark");
21
- const variables_dark_17 = require("../../components/CodeBlock/variables.dark");
21
+ const variables_dark_17 = require("../../components/MissingTranslationNotice/variables.dark");
22
+ const variables_dark_18 = require("../../components/CodeBlock/variables.dark");
22
23
  const palette_dark_1 = require("./palette.dark");
23
24
  const replayDarkMode = (0, styled_components_1.css) `
24
25
  /**
@@ -359,10 +360,11 @@ exports.darkMode = (0, styled_components_1.css) `
359
360
  ${variables_dark_14.tooltipDarkMode}
360
361
  ${variables_dark_15.bannerDarkMode}
361
362
  ${variables_dark_16.admonitionDarkMode}
363
+ ${variables_dark_17.missingTranslationNoticeDarkMode}
362
364
  ${badgesDarkMode}
363
365
  ${numberedListDarkMode}
364
366
  ${palette_dark_1.activeBrandPaletteDark}
365
- ${variables_dark_17.codeBlockDarkMode}
367
+ ${variables_dark_18.codeBlockDarkMode}
366
368
  /**
367
369
  * @tokens Dark Theme Scrollbar Config
368
370
  * @presenter Color
@@ -20,39 +20,40 @@ const variables_15 = require("../../components/Dropdown/variables");
20
20
  const variables_16 = require("../../components/Tooltip/variables");
21
21
  const variables_17 = require("../../icons/CheckboxIcon/variables");
22
22
  const variables_18 = require("../../components/Admonition/variables");
23
- const variables_19 = require("../../components/Footer/variables");
24
- const variables_20 = require("../../components/Button/variables");
25
- const variables_21 = require("../../components/Buttons/variables");
26
- const variables_22 = require("../../components/Navbar/variables");
27
- const variables_23 = require("../../components/Search/variables");
28
- const variables_24 = require("../../components/Menu/variables");
29
- const variables_25 = require("../../components/CodeBlock/variables");
30
- const variables_26 = require("../../components/Product/variables");
31
- const variables_27 = require("../../components/Markdown/variables");
32
- const variables_28 = require("../../components/Banner/variables");
33
- const variables_29 = require("../../components/Consent/variables");
34
- const variables_30 = require("../../markdoc/components/Accordion/variables");
35
- const variables_31 = require("../../markdoc/components/Tabs/variables");
36
- const variables_32 = require("../../markdoc/components/NumberedList/variables");
37
- const variables_33 = require("../../markdoc/components/Diagram/variables");
38
- const variables_34 = require("../../components/LastUpdated/variables");
39
- const variables_35 = require("../../components/Logo/variables");
40
- const variables_36 = require("../../components/StatusCode/variables");
41
- const variables_37 = require("../../components/Segmented/variables");
42
- const variables_38 = require("../../components/UserMenu/variables");
43
- const variables_39 = require("../../components/Tags/variables");
44
- const variables_40 = require("../../components/VersionPicker/variables");
45
- const variables_41 = require("../../components/DatePicker/variables");
46
- const variables_42 = require("../../components/Switch/variables");
47
- const variables_43 = require("../../markdoc/components/Cards/variables");
48
- const variables_44 = require("../../markdoc/components/Prompt/variables");
49
- const variables_45 = require("../../markdoc/components/CodeWalkthrough/variables");
50
- const variables_46 = require("../../components/SkipContent/variables");
51
- const variables_47 = require("../../components/PageActions/variables");
52
- const variables_48 = require("../../components/SvgViewer/variables");
53
- const variables_49 = require("../../components/Toast/variables");
54
- const variables_50 = require("../../components/PageNavigation/variables");
55
- const variables_51 = require("../../components/NavigationTabs/variables");
23
+ const variables_19 = require("../../components/MissingTranslationNotice/variables");
24
+ const variables_20 = require("../../components/Footer/variables");
25
+ const variables_21 = require("../../components/Button/variables");
26
+ const variables_22 = require("../../components/Buttons/variables");
27
+ const variables_23 = require("../../components/Navbar/variables");
28
+ const variables_24 = require("../../components/Search/variables");
29
+ const variables_25 = require("../../components/Menu/variables");
30
+ const variables_26 = require("../../components/CodeBlock/variables");
31
+ const variables_27 = require("../../components/Product/variables");
32
+ const variables_28 = require("../../components/Markdown/variables");
33
+ const variables_29 = require("../../components/Banner/variables");
34
+ const variables_30 = require("../../components/Consent/variables");
35
+ const variables_31 = require("../../markdoc/components/Accordion/variables");
36
+ const variables_32 = require("../../markdoc/components/Tabs/variables");
37
+ const variables_33 = require("../../markdoc/components/NumberedList/variables");
38
+ const variables_34 = require("../../markdoc/components/Diagram/variables");
39
+ const variables_35 = require("../../components/LastUpdated/variables");
40
+ const variables_36 = require("../../components/Logo/variables");
41
+ const variables_37 = require("../../components/StatusCode/variables");
42
+ const variables_38 = require("../../components/Segmented/variables");
43
+ const variables_39 = require("../../components/UserMenu/variables");
44
+ const variables_40 = require("../../components/Tags/variables");
45
+ const variables_41 = require("../../components/VersionPicker/variables");
46
+ const variables_42 = require("../../components/DatePicker/variables");
47
+ const variables_43 = require("../../components/Switch/variables");
48
+ const variables_44 = require("../../markdoc/components/Cards/variables");
49
+ const variables_45 = require("../../markdoc/components/Prompt/variables");
50
+ const variables_46 = require("../../markdoc/components/CodeWalkthrough/variables");
51
+ const variables_47 = require("../../components/SkipContent/variables");
52
+ const variables_48 = require("../../components/PageActions/variables");
53
+ const variables_49 = require("../../components/SvgViewer/variables");
54
+ const variables_50 = require("../../components/Toast/variables");
55
+ const variables_51 = require("../../components/PageNavigation/variables");
56
+ const variables_52 = require("../../components/NavigationTabs/variables");
56
57
  const utils_1 = require("../../core/utils");
57
58
  const palette_1 = require("./palette");
58
59
  const dark_1 = require("./dark");
@@ -1272,50 +1273,51 @@ const replay = (0, styled_components_1.css) `
1272
1273
  exports.tokens = (0, styled_components_1.css) `
1273
1274
  ${variables_13.accordion}
1274
1275
  ${variables_18.admonition}
1276
+ ${variables_19.missingTranslationNotice}
1275
1277
  ${apiReferenceDocs}
1276
1278
  ${variables_12.apiReferencePanels}
1277
1279
  ${badges}
1278
- ${variables_28.banner}
1280
+ ${variables_29.banner}
1279
1281
  ${borders}
1280
- ${variables_29.consent}
1282
+ ${variables_30.consent}
1281
1283
  ${variables_5.breadcrumbs}
1282
- ${variables_20.button}
1283
- ${variables_21.aiAssistantButton}
1284
- ${variables_21.connectMcpButton}
1285
- ${variables_43.cards}
1286
- ${variables_44.promptTag}
1284
+ ${variables_21.button}
1285
+ ${variables_22.aiAssistantButton}
1286
+ ${variables_22.connectMcpButton}
1287
+ ${variables_44.cards}
1288
+ ${variables_45.promptTag}
1287
1289
  ${variables_8.catalog}
1288
1290
  ${variables_11.catalogClassic}
1289
- ${variables_25.code}
1290
- ${variables_45.codeWalkthrough}
1291
+ ${variables_26.code}
1292
+ ${variables_46.codeWalkthrough}
1291
1293
  ${docsDropdown}
1292
1294
  ${variables_15.dropdown}
1293
1295
  ${error}
1294
1296
  ${variables_10.filter}
1295
- ${variables_19.footer}
1297
+ ${variables_20.footer}
1296
1298
  ${headingsTypography}
1297
- ${variables_39.httpTag}
1299
+ ${variables_40.httpTag}
1298
1300
  ${variables_9.image}
1299
1301
  ${inputs}
1300
1302
  ${variables_1.languagePicker}
1301
- ${variables_34.lastUpdated}
1303
+ ${variables_35.lastUpdated}
1302
1304
  ${links}
1303
1305
  ${loadProgressBar}
1304
- ${variables_35.logo}
1305
- ${variables_27.markdown}
1306
- ${variables_30.markdownAccordion}
1307
- ${variables_31.markdownTabs}
1308
- ${variables_32.markdownNumberedList}
1309
- ${variables_33.diagram}
1310
- ${variables_24.menu}
1311
- ${variables_24.mobileMenu}
1306
+ ${variables_36.logo}
1307
+ ${variables_28.markdown}
1308
+ ${variables_31.markdownAccordion}
1309
+ ${variables_32.markdownTabs}
1310
+ ${variables_33.markdownNumberedList}
1311
+ ${variables_34.diagram}
1312
+ ${variables_25.menu}
1313
+ ${variables_25.mobileMenu}
1312
1314
  ${modal}
1313
- ${variables_22.navbar}
1315
+ ${variables_23.navbar}
1314
1316
  ${pages}
1315
- ${variables_26.productPicker}
1317
+ ${variables_27.productPicker}
1316
1318
  ${variables_12.responsePanelColors}
1317
- ${variables_23.search}
1318
- ${variables_51.navigationTabs}
1319
+ ${variables_24.search}
1320
+ ${variables_52.navigationTabs}
1319
1321
  ${variables_14.select}
1320
1322
  ${variables_4.sidebar}
1321
1323
  ${sizeAndSpace}
@@ -1326,26 +1328,26 @@ exports.tokens = (0, styled_components_1.css) `
1326
1328
  ${variables_7.toc}
1327
1329
  ${variables_16.tooltip}
1328
1330
  ${typography}
1329
- ${variables_38.userMenu}
1330
- ${variables_40.versionPicker}
1331
+ ${variables_39.userMenu}
1332
+ ${variables_41.versionPicker}
1331
1333
  ${zIndexDepth}
1332
1334
  ${scorecardColors}
1333
- ${variables_36.statusCode}
1335
+ ${variables_37.statusCode}
1334
1336
  ${tab}
1335
1337
  ${icon}
1336
1338
  ${tree}
1337
- ${variables_37.segmented}
1338
- ${variables_42.switcher}
1339
+ ${variables_38.segmented}
1340
+ ${variables_43.switcher}
1339
1341
  ${variables_17.checkbox}
1340
1342
  ${variables_3.feedback}
1341
1343
  ${variables_2.scorecard}
1342
- ${variables_41.datePicker}
1344
+ ${variables_42.datePicker}
1343
1345
  ${replay}
1344
- ${variables_46.skipContent}
1345
- ${variables_47.pageActions}
1346
- ${variables_48.svgViewer}
1347
- ${variables_49.toast}
1348
- ${variables_50.pageNavigation}
1346
+ ${variables_47.skipContent}
1347
+ ${variables_48.pageActions}
1348
+ ${variables_49.svgViewer}
1349
+ ${variables_50.toast}
1350
+ ${variables_51.pageNavigation}
1349
1351
 
1350
1352
  `;
1351
1353
  exports.styles = (0, styled_components_1.css) `
@@ -11,7 +11,7 @@ import type { ItemState, DrilldownMenuItemDetails } from './sidebar';
11
11
  import type { NavigationTabsState } from './navigation-tabs';
12
12
  import type { SearchItemData, SearchFacet, SearchFilterItem, SearchFacetQuery, AiSearchConversationItem, ContentSegment, ToolCall } from './search';
13
13
  import type { SubmitFeedbackParams } from './feedback';
14
- import type { TFunction } from './l10n';
14
+ import type { Locale, TFunction } from './l10n';
15
15
  import type { BreadcrumbItem } from './breadcrumb';
16
16
  import type { UseConsentResult } from './consent';
17
17
  import type { AiSearchError } from '../constants/search';
@@ -185,8 +185,5 @@ export type ThemeHooks = {
185
185
  export type L10nConfig = {
186
186
  currentLocale: string;
187
187
  defaultLocale: string;
188
- locales: {
189
- code: string;
190
- name: string;
191
- }[];
188
+ locales: Locale[];
192
189
  };