@redocly/theme 0.70.0-next.6 → 0.70.0-next.8
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.
- package/lib/components/Buttons/ConnectMCPButton.js +11 -1
- package/lib/components/Buttons/variables.d.ts +1 -0
- package/lib/components/Buttons/variables.js +4 -1
- package/lib/components/Catalog/Catalog.js +2 -2
- package/lib/components/JsonViewer/Helpers.js +3 -3
- package/lib/components/MCP/McpConnectionTabs.js +9 -2
- package/lib/components/Portal/Portal.js +37 -5
- package/lib/components/Search/SearchAiActionButtons.js +8 -3
- package/lib/components/Search/SearchDialog.js +10 -0
- package/lib/components/Search/SearchItem.js +1 -1
- package/lib/components/Search/SearchTrigger.js +33 -8
- package/lib/components/Search/variables.js +2 -0
- package/lib/core/constants/mcp.d.ts +2 -2
- package/lib/core/constants/mcp.js +1 -1
- package/lib/core/contexts/PortalContainerContext.d.ts +2 -0
- package/lib/core/contexts/PortalContainerContext.js +7 -0
- package/lib/core/hooks/code-walkthrough/use-code-panel.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +1 -2
- package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +1 -1
- package/lib/core/hooks/index.d.ts +1 -0
- package/lib/core/hooks/index.js +1 -0
- package/lib/core/hooks/search/use-persisted-quick-filter.d.ts +21 -0
- package/lib/core/hooks/search/use-persisted-quick-filter.js +92 -0
- package/lib/core/hooks/use-connect-mcp-button.js +1 -0
- package/lib/core/hooks/use-page-actions.d.ts +1 -1
- package/lib/core/hooks/use-page-actions.js +6 -0
- package/lib/core/styles/global.js +1 -0
- package/lib/core/types/code-walkthrough.d.ts +84 -0
- package/lib/core/types/hooks.d.ts +1 -1
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/mcp.d.ts +1 -1
- package/lib/core/utils/download-code-walkthrough.d.ts +1 -1
- package/lib/core/utils/get-code-walkthrough-file-text.d.ts +1 -1
- package/lib/core/utils/match-code-walkthrough-conditions.d.ts +1 -1
- package/lib/core/utils/mcp.js +7 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.d.ts +1 -1
- package/lib/markdoc/components/Tabs/TabList.js +8 -6
- package/lib/markdoc/tags/code-walkthrough.d.ts +1 -1
- package/package.json +4 -3
- package/src/components/Buttons/ConnectMCPButton.tsx +13 -2
- package/src/components/Buttons/variables.ts +4 -0
- package/src/components/Catalog/Catalog.tsx +5 -3
- package/src/components/JsonViewer/Helpers.tsx +5 -3
- package/src/components/MCP/McpConnectionTabs.tsx +22 -5
- package/src/components/Portal/Portal.tsx +4 -2
- package/src/components/Search/SearchAiActionButtons.tsx +31 -19
- package/src/components/Search/SearchDialog.tsx +11 -0
- package/src/components/Search/SearchItem.tsx +3 -1
- package/src/components/Search/SearchTrigger.tsx +42 -7
- package/src/components/Search/variables.ts +2 -0
- package/src/core/constants/mcp.ts +1 -1
- package/src/core/contexts/PortalContainerContext.tsx +4 -0
- package/src/core/hooks/__mocks__/index.ts +1 -0
- package/src/core/hooks/code-walkthrough/use-code-panel.ts +1 -1
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +2 -2
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -1
- package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +3 -3
- package/src/core/hooks/code-walkthrough/use-renderable-files.ts +1 -1
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/search/use-persisted-quick-filter.ts +125 -0
- package/src/core/hooks/use-connect-mcp-button.ts +7 -1
- package/src/core/hooks/use-page-actions.ts +17 -0
- package/src/core/styles/global.ts +2 -1
- package/src/core/types/code-walkthrough.ts +103 -0
- package/src/core/types/hooks.ts +1 -0
- package/src/core/types/l10n.ts +6 -0
- package/src/core/types/mcp.ts +1 -1
- package/src/core/utils/download-code-walkthrough.ts +1 -1
- package/src/core/utils/get-code-walkthrough-file-text.ts +1 -1
- package/src/core/utils/match-code-walkthrough-conditions.ts +1 -1
- package/src/core/utils/mcp.ts +8 -2
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -1
- package/src/markdoc/components/Tabs/TabList.tsx +9 -12
- package/src/markdoc/tags/code-walkthrough.ts +1 -1
|
@@ -34,6 +34,13 @@ const MENU_OPTIONS = {
|
|
|
34
34
|
descriptionTranslationKey: 'page.actions.connectMcp.vscodeDescription',
|
|
35
35
|
descriptionDefault: 'Install MCP server on VS Code',
|
|
36
36
|
},
|
|
37
|
+
claude: {
|
|
38
|
+
icon: ClaudeIcon_1.ClaudeIcon,
|
|
39
|
+
titleTranslationKey: 'page.actions.connectMcp.claude',
|
|
40
|
+
titleDefault: 'Connect to Claude',
|
|
41
|
+
descriptionTranslationKey: 'page.actions.connectMcp.claudeDescription',
|
|
42
|
+
descriptionDefault: 'Add MCP server to your Claude account',
|
|
43
|
+
},
|
|
37
44
|
'claude-code': {
|
|
38
45
|
icon: ClaudeIcon_1.ClaudeIcon,
|
|
39
46
|
titleTranslationKey: 'page.actions.connectMcp.claudeCode',
|
|
@@ -70,7 +77,7 @@ function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = c
|
|
|
70
77
|
const PrimaryIcon = primaryOption.icon;
|
|
71
78
|
const showPrimaryCopied = copiedOption === primaryOption.key;
|
|
72
79
|
return (react_1.default.createElement(ConnectMCPButtonWrapper, { "data-component-name": "Buttons/ConnectMCPButton" }, react_1.default.createElement(SplitButton_1.SplitButton, { variant: "secondary", placement: placement, alignment: alignment, closeOnSelect: false, toggleAriaLabel: translate('page.actions.connectMcp.moreOptions', 'More options'), button: react_1.default.createElement(Button_1.Button, { variant: "secondary", icon: showPrimaryCopied ? (react_1.default.createElement(CheckmarkFilledIcon_1.CheckmarkFilledIcon, { color: "var(--color-success-base)" })) : (react_1.default.createElement(PrimaryIcon, null)), onClick: () => handleAction(primaryOption.key) }, translate(primaryOption.titleTranslationKey, primaryOption.titleDefault)) }, dropdownOptions.length > 0
|
|
73
|
-
? ({ close }) => (react_1.default.createElement(
|
|
80
|
+
? ({ close }) => (react_1.default.createElement(StyledDropdownMenu, null, dropdownOptions.map((option) => {
|
|
74
81
|
const Icon = option.icon;
|
|
75
82
|
const showCheckmark = copiedOption === option.key;
|
|
76
83
|
return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: option.key, onAction: () => {
|
|
@@ -82,6 +89,9 @@ function ConnectMCPButton({ placement = 'bottom', alignment = 'end', options = c
|
|
|
82
89
|
})))
|
|
83
90
|
: null)));
|
|
84
91
|
}
|
|
92
|
+
const StyledDropdownMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
|
|
93
|
+
--dropdown-menu-max-height: var(--connect-mcp-button-dropdown-max-height);
|
|
94
|
+
`;
|
|
85
95
|
const ConnectMCPButtonWrapper = styled_components_1.default.div `
|
|
86
96
|
display: inline-block;
|
|
87
97
|
position: relative;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.aiAssistantButton = void 0;
|
|
3
|
+
exports.connectMcpButton = exports.aiAssistantButton = void 0;
|
|
4
4
|
const styled_components_1 = require("styled-components");
|
|
5
5
|
/* eslint-disable theme/no-raw-colors-in-styles */
|
|
6
6
|
exports.aiAssistantButton = (0, styled_components_1.css) `
|
|
@@ -52,4 +52,7 @@ exports.aiAssistantButton = (0, styled_components_1.css) `
|
|
|
52
52
|
// @tokens End
|
|
53
53
|
`;
|
|
54
54
|
/* eslint-enable theme/no-raw-colors-in-styles */
|
|
55
|
+
exports.connectMcpButton = (0, styled_components_1.css) `
|
|
56
|
+
--connect-mcp-button-dropdown-max-height: fit-content;
|
|
57
|
+
`;
|
|
55
58
|
//# sourceMappingURL=variables.js.map
|
|
@@ -94,9 +94,9 @@ function Catalog(props) {
|
|
|
94
94
|
react_1.default.createElement(CatalogPageContentWrapper, null,
|
|
95
95
|
react_1.default.createElement(CatalogTitleWrapper, null,
|
|
96
96
|
react_1.default.createElement(CatalogTitle, { "data-translation-key": catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.titleTranslationKey },
|
|
97
|
-
(catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.titleTranslationKey)
|
|
97
|
+
react_1.default.createElement("span", null, (catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.titleTranslationKey)
|
|
98
98
|
? translate(catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.titleTranslationKey)
|
|
99
|
-
: catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.slug,
|
|
99
|
+
: catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.slug),
|
|
100
100
|
' '),
|
|
101
101
|
react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, entitiesCounter)),
|
|
102
102
|
react_1.default.createElement(CatalogDescription, { "data-translation-key": catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.descriptionTranslationKey }, translate(catalogConfig === null || catalogConfig === void 0 ? void 0 : catalogConfig.descriptionTranslationKey)),
|
|
@@ -43,10 +43,10 @@ function JsonValue(props) {
|
|
|
43
43
|
const valueElement = Array.isArray(value)
|
|
44
44
|
? value.map((item, index) => (react_1.default.createElement(react_1.default.Fragment, { key: index },
|
|
45
45
|
react_1.default.createElement(JsonValue, { value: item, level: level + 1, path: `${path}/${index}`, standalone: true, fold: fold, maxStringLength: maxStringLength }),
|
|
46
|
-
index < value.length - 1 ? ',\n' : null)))
|
|
46
|
+
index < value.length - 1 ? react_1.default.createElement("span", null, ',\n') : null)))
|
|
47
47
|
: keys.map((key, index) => (react_1.default.createElement(react_1.default.Fragment, { key: key },
|
|
48
48
|
react_1.default.createElement(JsonKeyValue, { name: key, value: value[key], level: level + 1, path: `${path}/${key}`, fold: fold, maxStringLength: maxStringLength }),
|
|
49
|
-
index < keys.length - 1 ? ',\n' : null)));
|
|
49
|
+
index < keys.length - 1 ? react_1.default.createElement("span", null, ',\n') : null)));
|
|
50
50
|
const openingPunctuationElement = standalone ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
51
51
|
indent,
|
|
52
52
|
level > 0 ? (react_1.default.createElement(ExpandIcon, { onClick: () => fold.setExpanded(path, !isExpanded), isExpanded: isExpanded })) : null,
|
|
@@ -79,7 +79,7 @@ function JsonKeyValue(props) {
|
|
|
79
79
|
indent,
|
|
80
80
|
isFoldable(value) ? (react_1.default.createElement(ExpandIcon, { onClick: () => fold.setExpanded(path, !isExpanded), isExpanded: isExpanded })) : null,
|
|
81
81
|
react_1.default.createElement("span", { className: "property token string" }, `"${name}"`),
|
|
82
|
-
":
|
|
82
|
+
react_1.default.createElement("span", null, ': '),
|
|
83
83
|
valueElement));
|
|
84
84
|
}
|
|
85
85
|
function TruncatedStringValue({ value, maxStringLength, }) {
|
|
@@ -41,6 +41,7 @@ const react_1 = __importStar(require("react"));
|
|
|
41
41
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
42
42
|
const hooks_1 = require("../../core/hooks");
|
|
43
43
|
const utils_1 = require("../../core/utils");
|
|
44
|
+
const Button_1 = require("../../components/Button/Button");
|
|
44
45
|
const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
|
|
45
46
|
const ClaudeIcon_1 = require("../../icons/ClaudeIcon/ClaudeIcon");
|
|
46
47
|
const ChatGptIcon_1 = require("../../icons/ChatGptIcon/ChatGptIcon");
|
|
@@ -111,9 +112,11 @@ function renderTabContent(option, connection, translate, snippetHeader) {
|
|
|
111
112
|
react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "shell", source: (0, utils_1.generateClaudeCodeCommand)(connection), header: snippetHeader(option, 'claude-code'), wrapContents: true }))),
|
|
112
113
|
},
|
|
113
114
|
{
|
|
114
|
-
headline: translate('page.mcpNotAllowed.snippets.claudeDesktop.headline', 'Claude
|
|
115
|
+
headline: translate('page.mcpNotAllowed.snippets.claudeDesktop.headline', 'Claude app'),
|
|
115
116
|
content: (react_1.default.createElement(react_1.default.Fragment, null,
|
|
116
|
-
react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.claudeDesktop.
|
|
117
|
+
react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.claudeDesktop.accountHint', 'Claude adds the connector to your account and syncs it between Claude on the web and Claude Desktop.')),
|
|
118
|
+
react_1.default.createElement(ConnectButton, { variant: "secondary", icon: react_1.default.createElement(ClaudeIcon_1.ClaudeIcon, null), onClick: () => window.open((0, utils_1.generateMCPDeepLink)('claude', connection), '_blank') }, translate('page.actions.connectMcp.claude', 'Connect to Claude')),
|
|
119
|
+
react_1.default.createElement(TabHint, null, translate('page.mcpNotAllowed.snippets.claudeDesktop.instruction', 'Or open Customize → Connectors → Add custom connector and paste this server URL:')),
|
|
117
120
|
react_1.default.createElement(CodeBlock_1.CodeBlock, { lang: "text", source: connection.url, header: snippetHeader(option, 'claude-desktop') }))),
|
|
118
121
|
},
|
|
119
122
|
]);
|
|
@@ -154,6 +157,10 @@ const McpConnectionTabsWrapper = styled_components_1.default.div `
|
|
|
154
157
|
padding-right: var(--page-mcp-405-snippets-code-padding-right);
|
|
155
158
|
}
|
|
156
159
|
`;
|
|
160
|
+
const ConnectButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
161
|
+
align-self: flex-start;
|
|
162
|
+
margin-bottom: var(--spacing-sm);
|
|
163
|
+
`;
|
|
157
164
|
const TabHint = styled_components_1.default.p `
|
|
158
165
|
margin: 0 0 var(--spacing-xs);
|
|
159
166
|
color: var(--page-mcp-405-snippets-hint-text-color);
|
|
@@ -1,14 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
36
|
exports.Portal = Portal;
|
|
7
|
-
const react_1 =
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
8
38
|
const react_dom_1 = require("react-dom");
|
|
9
39
|
const utils_1 = require("../../core/utils");
|
|
40
|
+
const PortalContainerContext_1 = require("../../core/contexts/PortalContainerContext");
|
|
10
41
|
function Portal({ children, mountId = 'root', }) {
|
|
11
|
-
const
|
|
42
|
+
const container = (0, react_1.useContext)(PortalContainerContext_1.PortalContainerContext);
|
|
43
|
+
const mount = utils_1.IS_BROWSER ? container || document.getElementById(mountId) || document.body : null;
|
|
12
44
|
if (!mount) {
|
|
13
45
|
return react_1.default.createElement(react_1.default.Fragment, null, children);
|
|
14
46
|
}
|
|
@@ -13,11 +13,16 @@ const ThumbUpFilledIcon_1 = require("../../icons/ThumbUpFilledIcon/ThumbUpFilled
|
|
|
13
13
|
const ThumbDownIcon_1 = require("../../icons/ThumbDownIcon/ThumbDownIcon");
|
|
14
14
|
const ThumbDownFilledIcon_1 = require("../../icons/ThumbDownFilledIcon/ThumbDownFilledIcon");
|
|
15
15
|
const CopyButton_1 = require("../../components/Buttons/CopyButton");
|
|
16
|
+
const Tooltip_1 = require("../../components/Tooltip/Tooltip");
|
|
17
|
+
const hooks_1 = require("../../core/hooks");
|
|
16
18
|
function SearchAiActionButtons({ content, className, feedback, onFeedback, disabled, }) {
|
|
19
|
+
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
20
|
+
const { translate } = useTranslate();
|
|
17
21
|
return (react_1.default.createElement(ActionButtonsWrapper, { className: className, "data-component-name": "Search/SearchAiActionButtons" },
|
|
18
|
-
react_1.default.createElement(
|
|
19
|
-
|
|
20
|
-
react_1.default.createElement(FeedbackButton, { variant: "text", size: "small", icon: feedback === types_1.FeedbackType.
|
|
22
|
+
react_1.default.createElement(Tooltip_1.Tooltip, { tip: translate('search.ai.actions.copy', 'Copy the response'), placement: "top" },
|
|
23
|
+
react_1.default.createElement(CopyButton_1.CopyButton, { data: content })),
|
|
24
|
+
react_1.default.createElement(Tooltip_1.Tooltip, { tip: translate('search.ai.actions.like', 'Like the response'), placement: "top" }, react_1.default.createElement(FeedbackButton, { variant: "text", size: "small", icon: feedback === types_1.FeedbackType.Like ? react_1.default.createElement(ThumbUpFilledIcon_1.ThumbUpFilledIcon, null) : react_1.default.createElement(ThumbUpIcon_1.ThumbUpIcon, null), onClick: () => !disabled && onFeedback(types_1.FeedbackType.Like), extraClass: feedback === types_1.FeedbackType.Like ? 'active' : '', "aria-label": "Like this response", disabled: disabled })),
|
|
25
|
+
react_1.default.createElement(Tooltip_1.Tooltip, { tip: translate('search.ai.actions.dislike', 'Dislike the response'), placement: "top" }, react_1.default.createElement(FeedbackButton, { variant: "text", size: "small", icon: feedback === types_1.FeedbackType.Dislike ? react_1.default.createElement(ThumbDownFilledIcon_1.ThumbDownFilledIcon, null) : react_1.default.createElement(ThumbDownIcon_1.ThumbDownIcon, null), onClick: () => !disabled && onFeedback(types_1.FeedbackType.Dislike), extraClass: feedback === types_1.FeedbackType.Dislike ? 'active' : '', "aria-label": "Dislike this response", disabled: disabled }))));
|
|
21
26
|
}
|
|
22
27
|
const ActionButtonsWrapper = styled_components_1.default.div `
|
|
23
28
|
display: flex;
|
|
@@ -76,6 +76,16 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
|
|
|
76
76
|
const autoSearchDisabled = mode !== 'search';
|
|
77
77
|
const { query, setQuery, filter, setFilter, items, isSearchLoading, facets, groupCounts, setLoadMore, advancedSearch, askAi, groupField, searchError, retrySearch, } = useSearch(product === null || product === void 0 ? void 0 : product.name, autoSearchDisabled);
|
|
78
78
|
const { isFilterOpen, onFilterToggle, onFilterChange, onFilterReset, onFacetReset, onQuickFilterReset, } = (0, hooks_1.useSearchFilter)(filter, setFilter);
|
|
79
|
+
(0, hooks_1.usePersistedQuickFilter)({
|
|
80
|
+
filter,
|
|
81
|
+
setFilter,
|
|
82
|
+
facets,
|
|
83
|
+
groupField,
|
|
84
|
+
query,
|
|
85
|
+
isSearchLoading,
|
|
86
|
+
searchError,
|
|
87
|
+
enabled: initialMode === 'search',
|
|
88
|
+
});
|
|
79
89
|
const { addSearchHistoryItem } = (0, hooks_1.useRecentSearches)();
|
|
80
90
|
const aiSearch = useAiSearch({ filter: filter, product: product === null || product === void 0 ? void 0 : product.name });
|
|
81
91
|
(0, hooks_1.useModalScrollLock)(true);
|
|
@@ -76,7 +76,7 @@ function SearchItem({ onClick, item, className, product, innerRef, }) {
|
|
|
76
76
|
product.name)),
|
|
77
77
|
document.httpMethod ? (react_1.default.createElement(SearchItemOperation, null,
|
|
78
78
|
react_1.default.createElement(SearchItemOperationTag, { color: httpColor }, document.httpMethod.toUpperCase()),
|
|
79
|
-
highlight.httpPath ? (0, SearchHighlight_1.searchHighlight)(highlight.httpPath) : document.httpPath)) : null,
|
|
79
|
+
react_1.default.createElement("span", null, highlight.httpPath ? (0, SearchHighlight_1.searchHighlight)(highlight.httpPath) : document.httpPath))) : null,
|
|
80
80
|
react_1.default.createElement(SearchItemTitleWrapper, null,
|
|
81
81
|
react_1.default.createElement(SearchItemTitle, null, highlight.title ? (0, SearchHighlight_1.searchHighlight)(highlight.title) : document.title),
|
|
82
82
|
document.deprecated ? (react_1.default.createElement(SearchItemBadge, { deprecated: true }, translate('search.searchItem.deprecated', 'Deprecated'))) : null,
|
|
@@ -32,18 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.SearchTrigger = SearchTrigger;
|
|
40
37
|
const React = __importStar(require("react"));
|
|
41
|
-
const styled_components_1 =
|
|
38
|
+
const styled_components_1 = __importStar(require("styled-components"));
|
|
42
39
|
const hooks_1 = require("../../core/hooks");
|
|
43
40
|
const Button_1 = require("../../components/Button/Button");
|
|
44
41
|
const SearchIcon_1 = require("../../icons/SearchIcon/SearchIcon");
|
|
45
42
|
const utils_1 = require("../../core/utils");
|
|
46
43
|
const constants_1 = require("../../core/constants");
|
|
44
|
+
const MAC_SHORTCUT_LABEL = '⌘K';
|
|
45
|
+
const SHORTCUT_LABEL = 'Ctrl+K';
|
|
47
46
|
function SearchTrigger({ onClick, className }) {
|
|
48
47
|
var _a;
|
|
49
48
|
var _b;
|
|
@@ -61,8 +60,8 @@ function SearchTrigger({ onClick, className }) {
|
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
mainShortcutKey = mainShortcutKey === null || mainShortcutKey === void 0 ? void 0 : mainShortcutKey.toUpperCase();
|
|
64
|
-
// A page can be cached and served to every platform, so the server renders
|
|
65
|
-
//
|
|
63
|
+
// A page can be cached and served to every platform, so the server renders an empty
|
|
64
|
+
// slot and the browser picks the label after hydration.
|
|
66
65
|
const [isMac, setIsMac] = React.useState(undefined);
|
|
67
66
|
React.useEffect(() => setIsMac((0, utils_1.getUserAgent)().includes('Mac')), []);
|
|
68
67
|
return (React.createElement(SearchTriggerWrapper, { onClick: onClick, className: className, "data-component-name": "Search/SearchTrigger" },
|
|
@@ -70,7 +69,7 @@ function SearchTrigger({ onClick, className }) {
|
|
|
70
69
|
React.createElement(SearchTriggerInput, { "data-testid": "search-trigger-input", "data-translation-key": "search.navbar.label" },
|
|
71
70
|
React.createElement(SearchIcon_1.SearchIcon, null),
|
|
72
71
|
translate('search.navbar.label', 'Search'),
|
|
73
|
-
mainShortcutKey === constants_1.DEFAULT_KEYBOARD_SHORTCUTS ? (React.createElement(SearchTriggerShortcut,
|
|
72
|
+
mainShortcutKey === constants_1.DEFAULT_KEYBOARD_SHORTCUTS ? (React.createElement(SearchTriggerShortcut, null, isMac === undefined ? null : (React.createElement(SearchTriggerShortcutLabel, null, isMac ? MAC_SHORTCUT_LABEL : SHORTCUT_LABEL)))) : (React.createElement("span", null, mainShortcutKey)))));
|
|
74
73
|
}
|
|
75
74
|
const SearchTriggerWrapper = styled_components_1.default.div `
|
|
76
75
|
color: var(--search-trigger-color);
|
|
@@ -88,8 +87,34 @@ const SearchTriggerButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
|
88
87
|
display: none;
|
|
89
88
|
}
|
|
90
89
|
`;
|
|
90
|
+
// The hidden copy of the wider label keeps the slot the same width before and after
|
|
91
|
+
// hydration on every platform, so the trigger does not shift when the label appears.
|
|
91
92
|
const SearchTriggerShortcut = styled_components_1.default.span `
|
|
92
|
-
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
align-items: flex-end;
|
|
96
|
+
|
|
97
|
+
&::after {
|
|
98
|
+
content: '${SHORTCUT_LABEL}';
|
|
99
|
+
height: 0;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
visibility: hidden;
|
|
102
|
+
}
|
|
103
|
+
`;
|
|
104
|
+
const shortcutAppear = (0, styled_components_1.keyframes) `
|
|
105
|
+
from {
|
|
106
|
+
opacity: 0;
|
|
107
|
+
filter: blur(2px);
|
|
108
|
+
transform: translateY(3px);
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
const SearchTriggerShortcutLabel = styled_components_1.default.span `
|
|
112
|
+
animation: ${shortcutAppear} var(--search-trigger-shortcut-appear-duration)
|
|
113
|
+
var(--search-trigger-shortcut-appear-easing);
|
|
114
|
+
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
animation: none;
|
|
117
|
+
}
|
|
93
118
|
`;
|
|
94
119
|
const SearchTriggerInput = styled_components_1.default.div `
|
|
95
120
|
display: none;
|
|
@@ -146,6 +146,8 @@ exports.search = (0, styled_components_1.css) `
|
|
|
146
146
|
--search-trigger-bg-color: var(--navbar-bg-color);
|
|
147
147
|
--search-trigger-icon-size: 16px;
|
|
148
148
|
--search-trigger-line-height: var(--line-height-base);
|
|
149
|
+
--search-trigger-shortcut-appear-duration: 300ms;
|
|
150
|
+
--search-trigger-shortcut-appear-easing: ease-out;
|
|
149
151
|
|
|
150
152
|
/**
|
|
151
153
|
* @tokens AI Search
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const DEFAULT_MCP_SERVER_NAME = "mcp-server";
|
|
2
2
|
export declare const MCP_ROUTE = "/mcp";
|
|
3
3
|
export declare const PUBLIC_MCP_ROUTE = "/mcp-public";
|
|
4
|
-
export declare const MCP_OPTIONS: readonly ['cursor', 'vscode', 'claude-code', 'codex', 'copy'];
|
|
5
|
-
export declare const DEFAULT_MCP_OPTIONS: ("claude-code" | "codex" | "copy" | "cursor" | "vscode")[];
|
|
4
|
+
export declare const MCP_OPTIONS: readonly ['cursor', 'vscode', 'claude', 'claude-code', 'codex', 'copy'];
|
|
5
|
+
export declare const DEFAULT_MCP_OPTIONS: ("claude" | "claude-code" | "codex" | "copy" | "cursor" | "vscode")[];
|
|
@@ -4,6 +4,6 @@ exports.DEFAULT_MCP_OPTIONS = exports.MCP_OPTIONS = exports.PUBLIC_MCP_ROUTE = e
|
|
|
4
4
|
exports.DEFAULT_MCP_SERVER_NAME = 'mcp-server';
|
|
5
5
|
exports.MCP_ROUTE = '/mcp';
|
|
6
6
|
exports.PUBLIC_MCP_ROUTE = '/mcp-public';
|
|
7
|
-
exports.MCP_OPTIONS = ['cursor', 'vscode', 'claude-code', 'codex', 'copy'];
|
|
7
|
+
exports.MCP_OPTIONS = ['cursor', 'vscode', 'claude', 'claude-code', 'codex', 'copy'];
|
|
8
8
|
exports.DEFAULT_MCP_OPTIONS = [...exports.MCP_OPTIONS];
|
|
9
9
|
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PortalContainerContext = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
/** Where theme portals mount; set it inside a shadow root (the AI assistant web component), else `document.body`. */
|
|
6
|
+
exports.PortalContainerContext = (0, react_1.createContext)(null);
|
|
7
|
+
//# sourceMappingURL=PortalContainerContext.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CodeWalkthroughFile } from '
|
|
1
|
+
import type { CodeWalkthroughFile } from '../../../core/types';
|
|
2
2
|
export declare function useCodePanel(files: CodeWalkthroughFile[]): {
|
|
3
3
|
readonly activeFile: CodeWalkthroughFile;
|
|
4
4
|
readonly handleTabSwitch: (name: string) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CodeWalkthroughFile, CodeWalkthroughFilter, InputsMarkdocAttr, TogglesMarkdocAttr, CodeWalkthroughFilterItem, CodeWalkthroughConditionsObject } from '
|
|
1
|
+
import type { CodeWalkthroughFile, CodeWalkthroughFilter, InputsMarkdocAttr, TogglesMarkdocAttr, CodeWalkthroughFilterItem, CodeWalkthroughConditionsObject } from '../../../core/types';
|
|
2
2
|
export type ActiveFilter = {
|
|
3
3
|
id: string;
|
|
4
4
|
label?: string;
|
|
@@ -42,7 +42,7 @@ function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
|
42
42
|
Object.entries(newState).forEach(([id, control]) => {
|
|
43
43
|
const existingControl = controlsState[id];
|
|
44
44
|
if (existingControl && existingControl.type === control.type) {
|
|
45
|
-
// @ts-expect-error
|
|
45
|
+
// @ts-expect-error: TS2322 - the spread loses the link between `type` and `value` in the control union
|
|
46
46
|
newState[id] = Object.assign(Object.assign({}, control), { value: existingControl.value });
|
|
47
47
|
}
|
|
48
48
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CodeWalkthroughStepAttr } from '
|
|
1
|
+
import type { CodeWalkthroughStepAttr } from '../../../core/types';
|
|
2
2
|
import type { WalkthroughStepsState } from '../../types/code-walkthrough';
|
|
3
3
|
type CodeWalkthroughStep = CodeWalkthroughStepAttr & {
|
|
4
4
|
compRef?: HTMLElement;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { CodeWalkthroughFile, CodeWalkthroughStepAttr,
|
|
2
|
-
import type { WalkthroughStepsState } from '../../types/code-walkthrough';
|
|
1
|
+
import type { CodeWalkthroughAttr, CodeWalkthroughFile, CodeWalkthroughStepAttr, WalkthroughStepsState } from '../../types/code-walkthrough';
|
|
3
2
|
import { type WalkthroughControlsState } from './use-code-walkthrough-controls';
|
|
4
3
|
export type WalkthroughState = {
|
|
5
4
|
stepsState: WalkthroughStepsState;
|
|
@@ -31,6 +31,7 @@ export * from './search/use-search-dialog';
|
|
|
31
31
|
export * from './search/use-search-filter';
|
|
32
32
|
export * from './search/use-feedback-tooltip';
|
|
33
33
|
export * from './search/use-search-ai-activity';
|
|
34
|
+
export * from './search/use-persisted-quick-filter';
|
|
34
35
|
export * from './use-controlled-state';
|
|
35
36
|
export * from './use-codeblock-tabs-controls';
|
|
36
37
|
export * from './code-walkthrough/use-code-walkthrough';
|
package/lib/core/hooks/index.js
CHANGED
|
@@ -47,6 +47,7 @@ __exportStar(require("./search/use-search-dialog"), exports);
|
|
|
47
47
|
__exportStar(require("./search/use-search-filter"), exports);
|
|
48
48
|
__exportStar(require("./search/use-feedback-tooltip"), exports);
|
|
49
49
|
__exportStar(require("./search/use-search-ai-activity"), exports);
|
|
50
|
+
__exportStar(require("./search/use-persisted-quick-filter"), exports);
|
|
50
51
|
__exportStar(require("./use-controlled-state"), exports);
|
|
51
52
|
__exportStar(require("./use-codeblock-tabs-controls"), exports);
|
|
52
53
|
__exportStar(require("./code-walkthrough/use-code-walkthrough"), exports);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import type { SearchFacet, SearchFilterItem } from '../../types/search';
|
|
3
|
+
type UsePersistedQuickFilterOptions = {
|
|
4
|
+
filter: SearchFilterItem[];
|
|
5
|
+
setFilter: Dispatch<SetStateAction<SearchFilterItem[]>>;
|
|
6
|
+
facets: SearchFacet[];
|
|
7
|
+
groupField: string;
|
|
8
|
+
query: string;
|
|
9
|
+
isSearchLoading: boolean;
|
|
10
|
+
searchError: string | null;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Remembers the quick filter on `groupField` for the browser tab and restores it on mount unless
|
|
15
|
+
* one is already selected. Restored values are dropped once known not to exist: absent from the
|
|
16
|
+
* full value list, or from the `groupField` facet left by the first search that finishes without
|
|
17
|
+
* error on an empty query (the restored value is that search's filter, so a value without
|
|
18
|
+
* documents is not counted). Does nothing while `enabled` is false.
|
|
19
|
+
*/
|
|
20
|
+
export declare function usePersistedQuickFilter({ filter, setFilter, facets, groupField, query, isSearchLoading, searchError, enabled, }: UsePersistedQuickFilterOptions): void;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePersistedQuickFilter = usePersistedQuickFilter;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const use_store_1 = require("../use-store");
|
|
6
|
+
const quickFilterStore = (0, use_store_1.createStore)({
|
|
7
|
+
storageKey: 'searchQuickFilter',
|
|
8
|
+
storageType: 'sessionStorage',
|
|
9
|
+
});
|
|
10
|
+
const findQuickFilter = (filter) => filter.find((item) => item.isQuickFilter);
|
|
11
|
+
const withQuickFilter = (filter, quickFilter) => [
|
|
12
|
+
...filter.filter((item) => !item.isQuickFilter),
|
|
13
|
+
...(quickFilter.values.length ? [Object.assign(Object.assign({}, quickFilter), { isQuickFilter: true })] : []),
|
|
14
|
+
];
|
|
15
|
+
const groupFacetValues = (facets, field) => {
|
|
16
|
+
var _a;
|
|
17
|
+
const facet = facets.find((item) => item.field === field);
|
|
18
|
+
const values = (_a = facet === null || facet === void 0 ? void 0 : facet.values) !== null && _a !== void 0 ? _a : [];
|
|
19
|
+
return {
|
|
20
|
+
present: facet !== undefined,
|
|
21
|
+
values: values.map((item) => (typeof item === 'string' ? item : item.value)),
|
|
22
|
+
counted: values.some((item) => typeof item !== 'string' && item.isCounterVisible),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const isRestorable = (stored, groupField) => !!stored &&
|
|
26
|
+
stored.field === groupField &&
|
|
27
|
+
Array.isArray(stored.values) &&
|
|
28
|
+
stored.values.length > 0 &&
|
|
29
|
+
stored.values.every((value) => typeof value === 'string');
|
|
30
|
+
/**
|
|
31
|
+
* Remembers the quick filter on `groupField` for the browser tab and restores it on mount unless
|
|
32
|
+
* one is already selected. Restored values are dropped once known not to exist: absent from the
|
|
33
|
+
* full value list, or from the `groupField` facet left by the first search that finishes without
|
|
34
|
+
* error on an empty query (the restored value is that search's filter, so a value without
|
|
35
|
+
* documents is not counted). Does nothing while `enabled` is false.
|
|
36
|
+
*/
|
|
37
|
+
function usePersistedQuickFilter({ filter, setFilter, facets, groupField, query, isSearchLoading, searchError, enabled = true, }) {
|
|
38
|
+
const [stored, setStored] = (0, use_store_1.useStore)(quickFilterStore, null);
|
|
39
|
+
const [initial] = (0, react_1.useState)(() => enabled && isRestorable(stored, groupField) && !findQuickFilter(filter) ? stored.values : null);
|
|
40
|
+
const phaseRef = (0, react_1.useRef)(initial ? 'restoring' : 'done');
|
|
41
|
+
const searchedRef = (0, react_1.useRef)(false);
|
|
42
|
+
(0, react_1.useEffect)(() => {
|
|
43
|
+
if (!initial)
|
|
44
|
+
return;
|
|
45
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-pass-data-to-parent -- the filter state belongs to the product's `useSearch` and starts empty on every mount
|
|
46
|
+
setFilter((current) => withQuickFilter(current, { field: groupField, values: initial }));
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- applies only to the initial state
|
|
48
|
+
}, []);
|
|
49
|
+
(0, react_1.useEffect)(() => {
|
|
50
|
+
if (!enabled)
|
|
51
|
+
return;
|
|
52
|
+
const quickFilter = findQuickFilter(filter);
|
|
53
|
+
// The commit that starts the restore still sees the empty initial filter.
|
|
54
|
+
if (phaseRef.current === 'restoring') {
|
|
55
|
+
if (!quickFilter)
|
|
56
|
+
return;
|
|
57
|
+
phaseRef.current = 'validating';
|
|
58
|
+
}
|
|
59
|
+
if (phaseRef.current === 'validating' && initial) {
|
|
60
|
+
if (isSearchLoading)
|
|
61
|
+
searchedRef.current = true;
|
|
62
|
+
const settled = searchedRef.current && !isSearchLoading && !searchError && !query.trim();
|
|
63
|
+
const { present, values: known, counted } = groupFacetValues(facets, groupField);
|
|
64
|
+
if ((known.length && !counted) || (settled && present)) {
|
|
65
|
+
phaseRef.current = 'done';
|
|
66
|
+
const values = quickFilter === null || quickFilter === void 0 ? void 0 : quickFilter.values.filter((value) => known.includes(value) || !initial.includes(value));
|
|
67
|
+
if (quickFilter && values && values.length !== quickFilter.values.length) {
|
|
68
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-pass-data-to-parent -- the facets arrive after the restore
|
|
69
|
+
setFilter((current) => withQuickFilter(current, { field: groupField, values }));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const next = quickFilter ? { field: quickFilter.field, values: quickFilter.values } : null;
|
|
75
|
+
if (JSON.stringify(next) !== JSON.stringify(stored)) {
|
|
76
|
+
setStored(next);
|
|
77
|
+
}
|
|
78
|
+
}, [
|
|
79
|
+
enabled,
|
|
80
|
+
filter,
|
|
81
|
+
facets,
|
|
82
|
+
groupField,
|
|
83
|
+
query,
|
|
84
|
+
isSearchLoading,
|
|
85
|
+
searchError,
|
|
86
|
+
initial,
|
|
87
|
+
stored,
|
|
88
|
+
setFilter,
|
|
89
|
+
setStored,
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=use-persisted-quick-filter.js.map
|
|
@@ -41,6 +41,7 @@ function useConnectMCPButton({ options = mcp_1.DEFAULT_MCP_OPTIONS, } = {}) {
|
|
|
41
41
|
const urlMap = {
|
|
42
42
|
cursor: cursorUrl,
|
|
43
43
|
vscode: vscodeUrl,
|
|
44
|
+
claude: (0, mcp_2.generateMCPDeepLink)('claude', connection),
|
|
44
45
|
};
|
|
45
46
|
window.open(urlMap[action], '_blank');
|
|
46
47
|
}, [cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied, telemetry]);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { PageAction } from '../types';
|
|
2
|
-
export type PageActionType = 'copy' | 'view' | 'chatgpt' | 'claude' | 'docs-mcp-cursor' | 'docs-mcp-vscode' | 'mcp-cursor' | 'mcp-vscode';
|
|
2
|
+
export type PageActionType = 'copy' | 'view' | 'chatgpt' | 'claude' | 'docs-mcp-cursor' | 'docs-mcp-vscode' | 'docs-mcp-claude' | 'mcp-cursor' | 'mcp-vscode';
|
|
3
3
|
export declare function usePageActions(pageSlug: string, mcpUrl?: string, actions?: PageActionType[]): PageAction[];
|
|
@@ -32,6 +32,7 @@ const DEFAULT_ENABLED_ACTIONS = [
|
|
|
32
32
|
'claude',
|
|
33
33
|
'docs-mcp-cursor',
|
|
34
34
|
'docs-mcp-vscode',
|
|
35
|
+
'docs-mcp-claude',
|
|
35
36
|
];
|
|
36
37
|
function usePageActions(pageSlug, mcpUrl, actions) {
|
|
37
38
|
var _a;
|
|
@@ -84,6 +85,7 @@ function usePageActions(pageSlug, mcpUrl, actions) {
|
|
|
84
85
|
const actionHandlers = {
|
|
85
86
|
'docs-mcp-cursor': createMCPHandler('cursor', false),
|
|
86
87
|
'docs-mcp-vscode': createMCPHandler('vscode', false),
|
|
88
|
+
'docs-mcp-claude': createMCPHandler('claude', false),
|
|
87
89
|
'mcp-cursor': createMCPHandler('cursor', true),
|
|
88
90
|
'mcp-vscode': createMCPHandler('vscode', true),
|
|
89
91
|
copy: () => ({
|
|
@@ -189,6 +191,9 @@ function createMCPAction({ clientType, mcpConfig, translate, onClickCallback, })
|
|
|
189
191
|
if (clientType === 'cursor') {
|
|
190
192
|
return Object.assign(Object.assign({}, sharedProps), { buttonText: translate('page.actions.connectMcp.cursor', 'Connect to Cursor'), title: translate('page.actions.connectMcp.cursor', 'Connect to Cursor'), description: translate('page.actions.connectMcp.cursorDescription', 'Install MCP server on Cursor'), iconComponent: CursorIcon_1.CursorIcon });
|
|
191
193
|
}
|
|
194
|
+
if (clientType === 'claude') {
|
|
195
|
+
return Object.assign(Object.assign({}, sharedProps), { buttonText: translate('page.actions.connectMcp.claude', 'Connect to Claude'), title: translate('page.actions.connectMcp.claude', 'Connect to Claude'), description: translate('page.actions.connectMcp.claudeDescription', 'Add MCP server to your Claude account'), iconComponent: ClaudeIcon_1.ClaudeIcon });
|
|
196
|
+
}
|
|
192
197
|
return Object.assign(Object.assign({}, sharedProps), { buttonText: translate('page.actions.connectMcp.vscode', 'Connect to VS Code'), title: translate('page.actions.connectMcp.vscode', 'Connect to VS Code'), description: translate('page.actions.connectMcp.vscodeDescription', 'Install MCP server on VS Code'), iconComponent: VSCodeIcon_1.VSCodeIcon });
|
|
193
198
|
}
|
|
194
199
|
function shouldHideAction(action, { pageProps, themeConfig, apiDocsExcludeFromSearch, isApiDocsPage, isPublic, mcpUrl, isMcpDisabled, }) {
|
|
@@ -221,6 +226,7 @@ function shouldHideActionByType(action, { isPublic, mcpUrl, isMcpDisabled, }) {
|
|
|
221
226
|
return !isPublic;
|
|
222
227
|
case 'docs-mcp-cursor':
|
|
223
228
|
case 'docs-mcp-vscode':
|
|
229
|
+
case 'docs-mcp-claude':
|
|
224
230
|
return Boolean(mcpUrl) || isMcpDisabled;
|
|
225
231
|
case 'mcp-cursor':
|
|
226
232
|
case 'mcp-vscode':
|
|
@@ -1320,6 +1320,7 @@ exports.tokens = (0, styled_components_1.css) `
|
|
|
1320
1320
|
${variables_5.breadcrumbs}
|
|
1321
1321
|
${variables_20.button}
|
|
1322
1322
|
${variables_21.aiAssistantButton}
|
|
1323
|
+
${variables_21.connectMcpButton}
|
|
1323
1324
|
${variables_43.cards}
|
|
1324
1325
|
${variables_8.catalog}
|
|
1325
1326
|
${variables_11.catalogClassic}
|