@redocly/theme 0.62.0 → 0.63.0-next.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.
- package/lib/components/Badge/Badge.d.ts +2 -1
- package/lib/components/Badge/Badge.js +24 -2
- package/lib/components/Buttons/AIAssistantButton.js +1 -1
- package/lib/components/Menu/MenuItem.js +34 -11
- package/lib/components/Menu/variables.js +3 -3
- package/lib/components/PageActions/PageActions.js +25 -8
- package/lib/components/Search/SearchDialog.js +1 -0
- package/lib/core/hooks/use-mcp-config.js +2 -1
- package/lib/core/hooks/use-modal-scroll-lock.js +24 -10
- package/lib/core/hooks/use-page-actions.js +7 -2
- package/lib/core/styles/global.js +0 -4
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
- package/lib/markdoc/components/Heading/Heading.js +6 -0
- package/package.json +3 -3
- package/src/components/Badge/Badge.tsx +18 -2
- package/src/components/Buttons/AIAssistantButton.tsx +1 -1
- package/src/components/Menu/MenuItem.tsx +54 -12
- package/src/components/Menu/variables.ts +3 -3
- package/src/components/PageActions/PageActions.tsx +38 -15
- package/src/components/Search/SearchDialog.tsx +2 -1
- package/src/core/hooks/use-mcp-config.ts +2 -1
- package/src/core/hooks/use-modal-scroll-lock.ts +29 -10
- package/src/core/hooks/use-page-actions.ts +7 -2
- package/src/core/styles/global.ts +0 -4
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
- package/src/markdoc/components/Heading/Heading.tsx +6 -0
|
@@ -4,5 +4,6 @@ export type BadgeProps = PropsWithChildren<{
|
|
|
4
4
|
color?: string;
|
|
5
5
|
key?: string;
|
|
6
6
|
className?: string;
|
|
7
|
+
icon?: string;
|
|
7
8
|
}>;
|
|
8
|
-
export declare function Badge(props: BadgeProps): JSX.Element;
|
|
9
|
+
export declare function Badge({ icon, children, ...props }: BadgeProps): JSX.Element;
|
|
@@ -32,6 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
36
|
+
var t = {};
|
|
37
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
38
|
+
t[p] = s[p];
|
|
39
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
40
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
41
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
42
|
+
t[p[i]] = s[p[i]];
|
|
43
|
+
}
|
|
44
|
+
return t;
|
|
45
|
+
};
|
|
35
46
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
47
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
48
|
};
|
|
@@ -39,8 +50,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
50
|
exports.Badge = Badge;
|
|
40
51
|
const react_1 = __importDefault(require("react"));
|
|
41
52
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
|
|
54
|
+
function Badge(_a) {
|
|
55
|
+
var { icon, children } = _a, props = __rest(_a, ["icon", "children"]);
|
|
56
|
+
return (react_1.default.createElement(BadgeComponent, Object.assign({}, props, { "data-component-name": "Badge/Badge" }),
|
|
57
|
+
icon ? react_1.default.createElement(BadgeIcon, { icon: icon }) : null,
|
|
58
|
+
children));
|
|
44
59
|
}
|
|
45
60
|
const BadgeComponent = styled_components_1.default.span `
|
|
46
61
|
display: inline-block;
|
|
@@ -61,4 +76,11 @@ const BadgeComponent = styled_components_1.default.span `
|
|
|
61
76
|
border-radius: var(--badge-deprecated-border-radius);
|
|
62
77
|
`}
|
|
63
78
|
`;
|
|
79
|
+
const BadgeIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
|
|
80
|
+
--icon-width: var(--font-size-sm);
|
|
81
|
+
--icon-height: var(--font-size-sm);
|
|
82
|
+
margin-right: var(--spacing-xxs);
|
|
83
|
+
flex-shrink: 0;
|
|
84
|
+
vertical-align: middle;
|
|
85
|
+
`;
|
|
64
86
|
//# sourceMappingURL=Badge.js.map
|
|
@@ -105,7 +105,7 @@ function AIAssistantButton() {
|
|
|
105
105
|
const StyledAIAssistantButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
106
106
|
position: fixed;
|
|
107
107
|
bottom: var(--ai-assistant-button-bottom);
|
|
108
|
-
right: var(--ai-assistant-button-right);
|
|
108
|
+
right: calc(var(--ai-assistant-button-right) + var(--modal-scrollbar-width, 0px));
|
|
109
109
|
${({ $inputType }) => $inputType === 'icon'
|
|
110
110
|
? `
|
|
111
111
|
border-radius: var(--ai-assistant-button-border-radius-icon);
|
|
@@ -45,10 +45,10 @@ const HttpTag_1 = require("../../components/Tags/HttpTag");
|
|
|
45
45
|
const constants_1 = require("../../core/constants");
|
|
46
46
|
const utils_1 = require("../../core/utils");
|
|
47
47
|
const ArrowRightIcon_1 = require("../../icons/ArrowRightIcon/ArrowRightIcon");
|
|
48
|
-
const Badge_1 = require("../../components/Badge/Badge");
|
|
49
48
|
const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
|
|
49
|
+
const Tag_1 = require("../../components/Tag/Tag");
|
|
50
50
|
function MenuItem(props) {
|
|
51
|
-
var _a;
|
|
51
|
+
var _a, _b;
|
|
52
52
|
const { item, depth, className, onClick } = props;
|
|
53
53
|
const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
|
|
54
54
|
const { translate } = useTranslate();
|
|
@@ -92,9 +92,10 @@ function MenuItem(props) {
|
|
|
92
92
|
hasChevron ? react_1.default.createElement(ChevronWrapper, null, chevron) : null,
|
|
93
93
|
react_1.default.createElement(MenuItemIcon, { icon: item.icon, srcSet: item.srcSet }),
|
|
94
94
|
react_1.default.createElement(MenuItemLabelTextWrapper, null,
|
|
95
|
-
react_1.default.createElement(MenuItemLabel, null,
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
react_1.default.createElement(MenuItemLabel, null, (_a = item.badges) === null || _a === void 0 ? void 0 :
|
|
96
|
+
_a.filter(({ position }) => position === 'before').map(({ name, color, icon }) => (react_1.default.createElement(SidebarTag, { color: isDirectColorValue(color) ? undefined : color, "$bgColor": isDirectColorValue(color) ? color : undefined, key: name, icon: icon && react_1.default.createElement(BadgeIcon, { icon: icon }) }, name))),
|
|
97
|
+
react_1.default.createElement("span", null, translate(item.labelTranslationKey, item.label)), (_b = item.badges) === null || _b === void 0 ? void 0 :
|
|
98
|
+
_b.filter(({ position }) => position !== 'before').map(({ name, color, icon }) => (react_1.default.createElement(SidebarTag, { color: isDirectColorValue(color) ? undefined : color, "$bgColor": isDirectColorValue(color) ? color : undefined, key: name, icon: icon && react_1.default.createElement(BadgeIcon, { icon: icon }) }, name))),
|
|
98
99
|
item.external ? react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "var(--menu-item-external-icon-size)" }) : null),
|
|
99
100
|
item.sublabel ? (react_1.default.createElement(MenuItemSubLabel, null, translate(item.subLabelTranslationKey, item.sublabel))) : null),
|
|
100
101
|
isDrilldown ? react_1.default.createElement(ArrowRightIcon_1.ArrowRightIcon, { size: "12px" }) : null,
|
|
@@ -104,6 +105,12 @@ function MenuItem(props) {
|
|
|
104
105
|
isNested ? (react_1.default.createElement(MenuItemNestedWrapper, { depth: depth, ref: nestedMenuRef, style: style }, isExpanded || !canUnmount ? props.children : null)) : null,
|
|
105
106
|
item.separatorLine ? (react_1.default.createElement(MenuItemSeparatorLine, { depth: depth, linePosition: item.linePosition })) : null));
|
|
106
107
|
}
|
|
108
|
+
/* for backward compatibility */
|
|
109
|
+
function isDirectColorValue(color) {
|
|
110
|
+
if (!color)
|
|
111
|
+
return false;
|
|
112
|
+
return color.startsWith('#') || color.startsWith('rgb') || color.startsWith('hsl');
|
|
113
|
+
}
|
|
107
114
|
function generateClassName({ type, item, className, }) {
|
|
108
115
|
const classNames = [className, `menu-item-type-${type}`];
|
|
109
116
|
if (type === constants_1.MenuItemType.Separator) {
|
|
@@ -282,15 +289,31 @@ const MenuItemLabel = styled_components_1.default.span `
|
|
|
282
289
|
margin-right: var(--spacing-xxs);
|
|
283
290
|
}
|
|
284
291
|
`;
|
|
285
|
-
const
|
|
292
|
+
const SidebarTag = (0, styled_components_1.default)(Tag_1.Tag) `
|
|
293
|
+
${({ $bgColor }) => $bgColor && `background-color: ${$bgColor};`} /* for backward compatibility */
|
|
286
294
|
margin-left: 0;
|
|
287
|
-
background-color: ${({ color }) => color || 'var(--color-info-base)'};
|
|
288
295
|
font-size: var(--font-size-sm);
|
|
289
296
|
line-height: var(--line-height-sm);
|
|
290
297
|
padding: 0 var(--spacing-xxs);
|
|
291
|
-
max-width:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
298
|
+
max-width: 90px;
|
|
299
|
+
|
|
300
|
+
--tag-padding: 0 var(--spacing-xxs);
|
|
301
|
+
--tag-content-padding: 0;
|
|
302
|
+
--tag-font-size: var(--font-size-sm);
|
|
303
|
+
--tag-line-height: var(--line-height-sm);
|
|
304
|
+
vertical-align: middle;
|
|
305
|
+
|
|
306
|
+
${Tag_1.ContentWrapper} {
|
|
307
|
+
text-overflow: ellipsis;
|
|
308
|
+
white-space: nowrap;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
display: block;
|
|
311
|
+
}
|
|
312
|
+
`;
|
|
313
|
+
const BadgeIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
|
|
314
|
+
--icon-width: var(--font-size-sm);
|
|
315
|
+
--icon-height: var(--font-size-sm);
|
|
316
|
+
margin-right: var(--spacing-xxs);
|
|
317
|
+
flex-shrink: 0;
|
|
295
318
|
`;
|
|
296
319
|
//# sourceMappingURL=MenuItem.js.map
|
|
@@ -131,12 +131,12 @@ exports.mobileMenu = (0, styled_components_1.css) `
|
|
|
131
131
|
* @tokens Mobile Menu
|
|
132
132
|
* */
|
|
133
133
|
/* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
|
|
134
|
-
--menu-mobile-height: calc(100vh - var(--navbar-height)
|
|
135
|
-
--menu-mobile-height: calc(100dvh - var(--navbar-height)
|
|
134
|
+
--menu-mobile-height: calc(100vh - var(--navbar-height));
|
|
135
|
+
--menu-mobile-height: calc(100dvh - var(--navbar-height));
|
|
136
136
|
--menu-mobile-width: 100%;
|
|
137
137
|
--menu-mobile-z-index: var(--z-index-raised);
|
|
138
138
|
--menu-mobile-left: 0;
|
|
139
|
-
--menu-mobile-top:
|
|
139
|
+
--menu-mobile-top: var(--navbar-height);
|
|
140
140
|
--menu-mobile-transition: 0.5s;
|
|
141
141
|
--menu-mobile-bg: var(--bg-color); // @presenter Color
|
|
142
142
|
--menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
|
|
@@ -49,6 +49,7 @@ exports.PageActions = PageActions;
|
|
|
49
49
|
const react_1 = __importStar(require("react"));
|
|
50
50
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
51
51
|
const PageActionsMenuItem_1 = require("../../components/PageActions/PageActionsMenuItem");
|
|
52
|
+
const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
|
|
52
53
|
const Link_1 = require("../../components/Link/Link");
|
|
53
54
|
const ButtonGroup_1 = require("../../components/Button/ButtonGroup");
|
|
54
55
|
const Button_1 = require("../../components/Button/Button");
|
|
@@ -77,16 +78,18 @@ function PageActions(props) {
|
|
|
77
78
|
setActionState('idle');
|
|
78
79
|
}, ACTION_DONE_DISPLAY_DURATION);
|
|
79
80
|
});
|
|
80
|
-
const menuItems = actions.map((action) =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
const menuItems = actions.map((action, index) => {
|
|
82
|
+
const key = `${action.title}-${index}`;
|
|
83
|
+
const hasLink = 'link' in action;
|
|
84
|
+
const content = hasLink ? (react_1.default.createElement(LinkMenuItem, { key: `${key}-link`, to: action.link, tabIndex: -1, external: true },
|
|
85
|
+
react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action }))) : (react_1.default.createElement(PageActionsMenuItem_1.PageActionsMenuItem, { pageAction: action }));
|
|
86
|
+
return (react_1.default.createElement(StyledDropdownMenuItem, { key: key, onAction: () => handleActionClick(action) }, content));
|
|
87
|
+
});
|
|
88
|
+
return (react_1.default.createElement(PageActionsWrapper, { "data-component-name": "PageActions/PageActions" },
|
|
86
89
|
react_1.default.createElement(ButtonGroup_1.ButtonGroup, { variant: "outlined", size: "medium" },
|
|
87
90
|
react_1.default.createElement(Button_1.Button, { icon: renderIcon(buttonAction, actionState), to: 'link' in buttonAction ? buttonAction.link : undefined, external: true, onClick: () => handleActionClick(buttonAction) }, buttonAction.buttonText),
|
|
88
|
-
actions.length > 1 ? (react_1.default.createElement(
|
|
89
|
-
react_1.default.createElement(StyledDropdownMenu,
|
|
91
|
+
actions.length > 1 ? (react_1.default.createElement(StyledDropdown, { withArrow: true, trigger: react_1.default.createElement(Button_1.Button, null), placement: "bottom", alignment: "end" },
|
|
92
|
+
react_1.default.createElement(StyledDropdownMenu, null, menuItems))) : null)));
|
|
90
93
|
}
|
|
91
94
|
function renderIcon(buttonAction, actionState) {
|
|
92
95
|
switch (actionState) {
|
|
@@ -111,7 +114,21 @@ const LinkMenuItem = (0, styled_components_1.default)(Link_1.Link) `
|
|
|
111
114
|
text-decoration: none;
|
|
112
115
|
--link-decoration-hover: none;
|
|
113
116
|
`;
|
|
117
|
+
const StyledDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
|
|
118
|
+
z-index: calc(var(--z-index-raised) - 1);
|
|
119
|
+
`;
|
|
114
120
|
const StyledDropdownMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
|
|
115
121
|
--dropdown-menu-max-height: var(--page-actions-dropdown-max-height);
|
|
116
122
|
`;
|
|
123
|
+
const StyledDropdownMenuItem = (0, styled_components_1.default)(DropdownMenuItem_1.DropdownMenuItem) `
|
|
124
|
+
&:has(a) {
|
|
125
|
+
padding: 0;
|
|
126
|
+
& > a {
|
|
127
|
+
display: inline-block;
|
|
128
|
+
width: 100%;
|
|
129
|
+
padding: var(--dropdown-menu-item-padding-vertical)
|
|
130
|
+
var(--dropdown-menu-item-padding-horizontal);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
117
134
|
//# sourceMappingURL=PageActions.js.map
|
|
@@ -74,6 +74,7 @@ function SearchDialog({ onClose, className, initialMode = 'search', }) {
|
|
|
74
74
|
const { isFilterOpen, onFilterToggle, onFilterChange, onFilterReset, onFacetReset, onQuickFilterReset, } = (0, hooks_1.useSearchFilter)(filter, setFilter);
|
|
75
75
|
const { addSearchHistoryItem } = (0, hooks_1.useRecentSearches)();
|
|
76
76
|
const aiSearch = useAiSearch({ filter });
|
|
77
|
+
(0, hooks_1.useModalScrollLock)(true);
|
|
77
78
|
const searchInputRef = (0, react_1.useRef)(null);
|
|
78
79
|
const modalRef = (0, react_1.useRef)(null);
|
|
79
80
|
const [isMobile, setIsMobile] = (0, react_1.useState)(false);
|
|
@@ -6,6 +6,7 @@ const use_theme_hooks_1 = require("./use-theme-hooks");
|
|
|
6
6
|
const dom_1 = require("../utils/dom");
|
|
7
7
|
const constants_1 = require("../constants");
|
|
8
8
|
const mcp_1 = require("../utils/mcp");
|
|
9
|
+
const urls_1 = require("../utils/urls");
|
|
9
10
|
function useMCPConfig() {
|
|
10
11
|
var _a;
|
|
11
12
|
const { useMcpData } = (0, use_theme_hooks_1.useThemeHooks)();
|
|
@@ -14,7 +15,7 @@ function useMCPConfig() {
|
|
|
14
15
|
? window.location.origin
|
|
15
16
|
: ((_a = globalThis['SSR_HOSTNAME']) !== null && _a !== void 0 ? _a : '');
|
|
16
17
|
const serverName = name || constants_1.DEFAULT_MCP_SERVER_NAME;
|
|
17
|
-
const serverUrl = `${origin}/mcp`;
|
|
18
|
+
const serverUrl = `${origin}${(0, urls_1.withPathPrefix)('/mcp')}`;
|
|
18
19
|
const isMcpDisabled = !enabled || false;
|
|
19
20
|
const cursorUrl = (0, react_1.useMemo)(() => (0, mcp_1.generateMCPDeepLink)('cursor', { serverName, url: serverUrl }), [serverName, serverUrl]);
|
|
20
21
|
const vscodeUrl = (0, react_1.useMemo)(() => (0, mcp_1.generateMCPDeepLink)('vscode', { serverName, url: serverUrl }), [serverName, serverUrl]);
|
|
@@ -4,19 +4,33 @@ exports.useModalScrollLock = useModalScrollLock;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
function useModalScrollLock(isOpen) {
|
|
6
6
|
(0, react_1.useEffect)(() => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (isOpen) {
|
|
10
|
-
document.body.style.overflow = 'hidden';
|
|
11
|
-
document.body.style.marginRight = `${scrollbarWidth}px`;
|
|
7
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
8
|
+
return;
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const { body, documentElement } = document;
|
|
11
|
+
const originalOverflow = body.style.overflow;
|
|
12
|
+
const originalPaddingRight = body.style.paddingRight;
|
|
13
|
+
const originalScrollbarWidth = documentElement.style.getPropertyValue('--modal-scrollbar-width');
|
|
14
|
+
const restoreScrollState = () => {
|
|
15
|
+
body.style.overflow = originalOverflow;
|
|
16
|
+
body.style.paddingRight = originalPaddingRight;
|
|
17
|
+
if (originalScrollbarWidth) {
|
|
18
|
+
documentElement.style.setProperty('--modal-scrollbar-width', originalScrollbarWidth);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
documentElement.style.removeProperty('--modal-scrollbar-width');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
if (isOpen) {
|
|
25
|
+
const scrollbarWidth = window.innerWidth - documentElement.clientWidth;
|
|
26
|
+
body.style.overflow = 'hidden';
|
|
27
|
+
if (scrollbarWidth > 0) {
|
|
28
|
+
body.style.paddingRight = `${scrollbarWidth}px`;
|
|
29
|
+
documentElement.style.setProperty('--modal-scrollbar-width', `${scrollbarWidth}px`);
|
|
30
|
+
}
|
|
16
31
|
}
|
|
17
32
|
return () => {
|
|
18
|
-
|
|
19
|
-
document.body.style.marginRight = '';
|
|
33
|
+
restoreScrollState();
|
|
20
34
|
};
|
|
21
35
|
}, [isOpen]);
|
|
22
36
|
}
|
|
@@ -119,22 +119,25 @@ function usePageActions(pageSlug, mcpUrl, actions) {
|
|
|
119
119
|
telemetry.sendPageActionsButtonClickedMessage([
|
|
120
120
|
Object.assign(Object.assign({}, createPageActionResource(pageSlug, pageUrl)), { action_type: 'view' }),
|
|
121
121
|
]);
|
|
122
|
+
window.location.href = mdPageUrl;
|
|
122
123
|
},
|
|
123
124
|
}),
|
|
124
125
|
chatgpt: () => {
|
|
125
126
|
if (!isPublic) {
|
|
126
127
|
return null;
|
|
127
128
|
}
|
|
129
|
+
const link = getExternalAiPromptLink('https://chat.openai.com', mdPageUrl);
|
|
128
130
|
return {
|
|
129
131
|
buttonText: translate('page.actions.chatGptButtonText', 'Open in ChatGPT'),
|
|
130
132
|
title: translate('page.actions.chatGptTitle', 'Open in ChatGPT'),
|
|
131
133
|
description: translate('page.actions.chatGptDescription', 'Get insights from ChatGPT'),
|
|
132
134
|
iconComponent: ChatGptIcon_1.ChatGptIcon,
|
|
133
|
-
link
|
|
135
|
+
link,
|
|
134
136
|
onClick: () => {
|
|
135
137
|
telemetry.sendPageActionsButtonClickedMessage([
|
|
136
138
|
Object.assign(Object.assign({}, createPageActionResource(pageSlug, pageUrl)), { action_type: 'chatgpt' }),
|
|
137
139
|
]);
|
|
140
|
+
window.location.href = link;
|
|
138
141
|
},
|
|
139
142
|
};
|
|
140
143
|
},
|
|
@@ -142,16 +145,18 @@ function usePageActions(pageSlug, mcpUrl, actions) {
|
|
|
142
145
|
if (!isPublic) {
|
|
143
146
|
return null;
|
|
144
147
|
}
|
|
148
|
+
const link = getExternalAiPromptLink('https://claude.ai/new', mdPageUrl);
|
|
145
149
|
return {
|
|
146
150
|
buttonText: translate('page.actions.claudeButtonText', 'Open in Claude'),
|
|
147
151
|
title: translate('page.actions.claudeTitle', 'Open in Claude'),
|
|
148
152
|
description: translate('page.actions.claudeDescription', 'Get insights from Claude'),
|
|
149
153
|
iconComponent: ClaudeIcon_1.ClaudeIcon,
|
|
150
|
-
link
|
|
154
|
+
link,
|
|
151
155
|
onClick: () => {
|
|
152
156
|
telemetry.sendPageActionsButtonClickedMessage([
|
|
153
157
|
Object.assign(Object.assign({}, createPageActionResource(pageSlug, pageUrl)), { action_type: 'claude' }),
|
|
154
158
|
]);
|
|
159
|
+
window.location.href = link;
|
|
155
160
|
},
|
|
156
161
|
};
|
|
157
162
|
},
|
|
@@ -1090,10 +1090,6 @@ const error = (0, styled_components_1.css) `
|
|
|
1090
1090
|
--compilation-error-file-header-margin: 0 0 var(--spacing-xs) 0;
|
|
1091
1091
|
`;
|
|
1092
1092
|
const modal = (0, styled_components_1.css) `
|
|
1093
|
-
body:has(.scroll-lock) {
|
|
1094
|
-
overflow: hidden;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
1093
|
--modal-box-shadow: var(--bg-raised-shadow);
|
|
1098
1094
|
--modal-bg-color: var(--bg-color);
|
|
1099
1095
|
`;
|
|
@@ -46,7 +46,7 @@ const FilterWrapper = styled_components_1.default.div `
|
|
|
46
46
|
padding-bottom: var(--spacing-xs);
|
|
47
47
|
top: var(--navbar-height);
|
|
48
48
|
background-color: var(--bg-color);
|
|
49
|
-
z-index:
|
|
49
|
+
z-index: var(--z-index-raised);
|
|
50
50
|
max-width: var(--md-content-max-width);
|
|
51
51
|
`;
|
|
52
52
|
const ButtonsWrapper = styled_components_1.default.div `
|
|
@@ -97,6 +97,12 @@ const HeadingContentWrapper = styled_components_1.default.div `
|
|
|
97
97
|
align-items: flex-start;
|
|
98
98
|
gap: var(--spacing-sm);
|
|
99
99
|
}
|
|
100
|
+
|
|
101
|
+
&:has([data-component-name='PageActions/PageActions']:hover) {
|
|
102
|
+
&& .anchor svg {
|
|
103
|
+
visibility: hidden;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
100
106
|
`;
|
|
101
107
|
const StyledHeadingText = styled_components_1.default.span `
|
|
102
108
|
margin: auto 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0-next.0",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vitest": "4.0.10",
|
|
64
64
|
"vitest-when": "0.6.2",
|
|
65
65
|
"webpack": "5.94.0",
|
|
66
|
-
"@redocly/realm-asyncapi-sdk": "0.
|
|
66
|
+
"@redocly/realm-asyncapi-sdk": "0.9.0-next.0"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@tanstack/react-query": "5.62.3",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"openapi-sampler": "1.6.2",
|
|
82
82
|
"react-calendar": "5.1.0",
|
|
83
83
|
"react-date-picker": "11.0.0",
|
|
84
|
-
"@redocly/config": "0.
|
|
84
|
+
"@redocly/config": "0.43.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"watch": "tsc -p tsconfig.build.json && (concurrently \"tsc -w -p tsconfig.build.json\" \"tsc-alias -w -p tsconfig.build.json\")",
|
|
@@ -3,15 +3,23 @@ import styled, { css } from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { PropsWithChildren, JSX } from 'react';
|
|
5
5
|
|
|
6
|
+
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
7
|
+
|
|
6
8
|
export type BadgeProps = PropsWithChildren<{
|
|
7
9
|
deprecated?: boolean;
|
|
8
10
|
color?: string;
|
|
9
11
|
key?: string;
|
|
10
12
|
className?: string;
|
|
13
|
+
icon?: string;
|
|
11
14
|
}>;
|
|
12
15
|
|
|
13
|
-
export function Badge(props: BadgeProps): JSX.Element {
|
|
14
|
-
return
|
|
16
|
+
export function Badge({ icon, children, ...props }: BadgeProps): JSX.Element {
|
|
17
|
+
return (
|
|
18
|
+
<BadgeComponent {...props} data-component-name="Badge/Badge">
|
|
19
|
+
{icon ? <BadgeIcon icon={icon} /> : null}
|
|
20
|
+
{children}
|
|
21
|
+
</BadgeComponent>
|
|
22
|
+
);
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
const BadgeComponent = styled.span<BadgeProps>`
|
|
@@ -34,3 +42,11 @@ const BadgeComponent = styled.span<BadgeProps>`
|
|
|
34
42
|
border-radius: var(--badge-deprecated-border-radius);
|
|
35
43
|
`}
|
|
36
44
|
`;
|
|
45
|
+
|
|
46
|
+
const BadgeIcon = styled(GenericIcon)`
|
|
47
|
+
--icon-width: var(--font-size-sm);
|
|
48
|
+
--icon-height: var(--font-size-sm);
|
|
49
|
+
margin-right: var(--spacing-xxs);
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
vertical-align: middle;
|
|
52
|
+
`;
|
|
@@ -111,7 +111,7 @@ export function AIAssistantButton() {
|
|
|
111
111
|
const StyledAIAssistantButton = styled(Button)<{ $inputType?: AIAssistantButtonType }>`
|
|
112
112
|
position: fixed;
|
|
113
113
|
bottom: var(--ai-assistant-button-bottom);
|
|
114
|
-
right: var(--ai-assistant-button-right);
|
|
114
|
+
right: calc(var(--ai-assistant-button-right) + var(--modal-scrollbar-width, 0px));
|
|
115
115
|
${({ $inputType }) =>
|
|
116
116
|
$inputType === 'icon'
|
|
117
117
|
? `
|
|
@@ -13,8 +13,8 @@ import { HttpTag } from '@redocly/theme/components/Tags/HttpTag';
|
|
|
13
13
|
import { MenuItemType } from '@redocly/theme/core/constants';
|
|
14
14
|
import { getMenuItemType, getOperationColor } from '@redocly/theme/core/utils';
|
|
15
15
|
import { ArrowRightIcon } from '@redocly/theme/icons/ArrowRightIcon/ArrowRightIcon';
|
|
16
|
-
import { Badge } from '@redocly/theme/components/Badge/Badge';
|
|
17
16
|
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
17
|
+
import { Tag, ContentWrapper } from '@redocly/theme/components/Tag/Tag';
|
|
18
18
|
|
|
19
19
|
export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Element {
|
|
20
20
|
const { item, depth, className, onClick } = props;
|
|
@@ -95,12 +95,31 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
95
95
|
<MenuItemIcon icon={item.icon} srcSet={item.srcSet} />
|
|
96
96
|
<MenuItemLabelTextWrapper>
|
|
97
97
|
<MenuItemLabel>
|
|
98
|
+
{item.badges
|
|
99
|
+
?.filter(({ position }) => position === 'before')
|
|
100
|
+
.map(({ name, color, icon }) => (
|
|
101
|
+
<SidebarTag
|
|
102
|
+
color={isDirectColorValue(color) ? undefined : color}
|
|
103
|
+
$bgColor={isDirectColorValue(color) ? color : undefined}
|
|
104
|
+
key={name}
|
|
105
|
+
icon={icon && <BadgeIcon icon={icon} />}
|
|
106
|
+
>
|
|
107
|
+
{name}
|
|
108
|
+
</SidebarTag>
|
|
109
|
+
))}
|
|
98
110
|
<span>{translate(item.labelTranslationKey, item.label)}</span>
|
|
99
|
-
{item.badges
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
{item.badges
|
|
112
|
+
?.filter(({ position }) => position !== 'before')
|
|
113
|
+
.map(({ name, color, icon }) => (
|
|
114
|
+
<SidebarTag
|
|
115
|
+
color={isDirectColorValue(color) ? undefined : color}
|
|
116
|
+
$bgColor={isDirectColorValue(color) ? color : undefined}
|
|
117
|
+
key={name}
|
|
118
|
+
icon={icon && <BadgeIcon icon={icon} />}
|
|
119
|
+
>
|
|
120
|
+
{name}
|
|
121
|
+
</SidebarTag>
|
|
122
|
+
))}
|
|
104
123
|
{item.external ? <LaunchIcon size="var(--menu-item-external-icon-size)" /> : null}
|
|
105
124
|
</MenuItemLabel>
|
|
106
125
|
{item.sublabel ? (
|
|
@@ -149,6 +168,12 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
149
168
|
);
|
|
150
169
|
}
|
|
151
170
|
|
|
171
|
+
/* for backward compatibility */
|
|
172
|
+
function isDirectColorValue(color?: string) {
|
|
173
|
+
if (!color) return false;
|
|
174
|
+
return color.startsWith('#') || color.startsWith('rgb') || color.startsWith('hsl');
|
|
175
|
+
}
|
|
176
|
+
|
|
152
177
|
function generateClassName({
|
|
153
178
|
type,
|
|
154
179
|
item,
|
|
@@ -362,14 +387,31 @@ const MenuItemLabel = styled.span`
|
|
|
362
387
|
}
|
|
363
388
|
`;
|
|
364
389
|
|
|
365
|
-
const
|
|
390
|
+
const SidebarTag = styled(Tag)<{ $bgColor?: string; icon?: React.ReactNode }>`
|
|
391
|
+
${({ $bgColor }) => $bgColor && `background-color: ${$bgColor};`} /* for backward compatibility */
|
|
366
392
|
margin-left: 0;
|
|
367
|
-
background-color: ${({ color }) => color || 'var(--color-info-base)'};
|
|
368
393
|
font-size: var(--font-size-sm);
|
|
369
394
|
line-height: var(--line-height-sm);
|
|
370
395
|
padding: 0 var(--spacing-xxs);
|
|
371
|
-
max-width:
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
396
|
+
max-width: 90px;
|
|
397
|
+
|
|
398
|
+
--tag-padding: 0 var(--spacing-xxs);
|
|
399
|
+
--tag-content-padding: 0;
|
|
400
|
+
--tag-font-size: var(--font-size-sm);
|
|
401
|
+
--tag-line-height: var(--line-height-sm);
|
|
402
|
+
vertical-align: middle;
|
|
403
|
+
|
|
404
|
+
${ContentWrapper} {
|
|
405
|
+
text-overflow: ellipsis;
|
|
406
|
+
white-space: nowrap;
|
|
407
|
+
overflow: hidden;
|
|
408
|
+
display: block;
|
|
409
|
+
}
|
|
410
|
+
`;
|
|
411
|
+
|
|
412
|
+
const BadgeIcon = styled(GenericIcon)`
|
|
413
|
+
--icon-width: var(--font-size-sm);
|
|
414
|
+
--icon-height: var(--font-size-sm);
|
|
415
|
+
margin-right: var(--spacing-xxs);
|
|
416
|
+
flex-shrink: 0;
|
|
375
417
|
`;
|
|
@@ -130,12 +130,12 @@ export const mobileMenu = css`
|
|
|
130
130
|
* @tokens Mobile Menu
|
|
131
131
|
* */
|
|
132
132
|
/* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
|
|
133
|
-
--menu-mobile-height: calc(100vh - var(--navbar-height)
|
|
134
|
-
--menu-mobile-height: calc(100dvh - var(--navbar-height)
|
|
133
|
+
--menu-mobile-height: calc(100vh - var(--navbar-height));
|
|
134
|
+
--menu-mobile-height: calc(100dvh - var(--navbar-height));
|
|
135
135
|
--menu-mobile-width: 100%;
|
|
136
136
|
--menu-mobile-z-index: var(--z-index-raised);
|
|
137
137
|
--menu-mobile-left: 0;
|
|
138
|
-
--menu-mobile-top:
|
|
138
|
+
--menu-mobile-top: var(--navbar-height);
|
|
139
139
|
--menu-mobile-transition: 0.5s;
|
|
140
140
|
--menu-mobile-bg: var(--bg-color); // @presenter Color
|
|
141
141
|
--menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
|
|
@@ -3,9 +3,9 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { PageAction } from '@redocly/theme/core/types';
|
|
6
|
-
import type { DropdownMenuItemProps } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
|
|
7
6
|
|
|
8
7
|
import { PageActionsMenuItem } from '@redocly/theme/components/PageActions/PageActionsMenuItem';
|
|
8
|
+
import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
|
|
9
9
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
10
10
|
import { ButtonGroup } from '@redocly/theme/components/Button/ButtonGroup';
|
|
11
11
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
@@ -52,20 +52,27 @@ export function PageActions(props: PageActionProps): JSX.Element | null {
|
|
|
52
52
|
}, ACTION_DONE_DISPLAY_DURATION);
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
const menuItems
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
) : (
|
|
55
|
+
const menuItems = actions.map((action, index) => {
|
|
56
|
+
const key = `${action.title}-${index}`;
|
|
57
|
+
const hasLink = 'link' in action;
|
|
58
|
+
|
|
59
|
+
const content = hasLink ? (
|
|
60
|
+
<LinkMenuItem key={`${key}-link`} to={action.link} tabIndex={-1} external>
|
|
62
61
|
<PageActionsMenuItem pageAction={action} />
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
</LinkMenuItem>
|
|
63
|
+
) : (
|
|
64
|
+
<PageActionsMenuItem pageAction={action} />
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<StyledDropdownMenuItem key={key} onAction={() => handleActionClick(action)}>
|
|
69
|
+
{content}
|
|
70
|
+
</StyledDropdownMenuItem>
|
|
71
|
+
);
|
|
72
|
+
});
|
|
66
73
|
|
|
67
74
|
return (
|
|
68
|
-
<PageActionsWrapper>
|
|
75
|
+
<PageActionsWrapper data-component-name="PageActions/PageActions">
|
|
69
76
|
<ButtonGroup variant="outlined" size="medium">
|
|
70
77
|
<Button
|
|
71
78
|
icon={renderIcon(buttonAction, actionState)}
|
|
@@ -76,9 +83,9 @@ export function PageActions(props: PageActionProps): JSX.Element | null {
|
|
|
76
83
|
{buttonAction.buttonText}
|
|
77
84
|
</Button>
|
|
78
85
|
{actions.length > 1 ? (
|
|
79
|
-
<
|
|
80
|
-
<StyledDropdownMenu
|
|
81
|
-
</
|
|
86
|
+
<StyledDropdown withArrow trigger={<Button />} placement="bottom" alignment="end">
|
|
87
|
+
<StyledDropdownMenu>{menuItems}</StyledDropdownMenu>
|
|
88
|
+
</StyledDropdown>
|
|
82
89
|
) : null}
|
|
83
90
|
</ButtonGroup>
|
|
84
91
|
</PageActionsWrapper>
|
|
@@ -111,6 +118,22 @@ const LinkMenuItem = styled(Link)`
|
|
|
111
118
|
--link-decoration-hover: none;
|
|
112
119
|
`;
|
|
113
120
|
|
|
121
|
+
const StyledDropdown = styled(Dropdown)`
|
|
122
|
+
z-index: calc(var(--z-index-raised) - 1);
|
|
123
|
+
`;
|
|
124
|
+
|
|
114
125
|
const StyledDropdownMenu = styled(DropdownMenu)`
|
|
115
126
|
--dropdown-menu-max-height: var(--page-actions-dropdown-max-height);
|
|
116
127
|
`;
|
|
128
|
+
|
|
129
|
+
const StyledDropdownMenuItem = styled(DropdownMenuItem)`
|
|
130
|
+
&:has(a) {
|
|
131
|
+
padding: 0;
|
|
132
|
+
& > a {
|
|
133
|
+
display: inline-block;
|
|
134
|
+
width: 100%;
|
|
135
|
+
padding: var(--dropdown-menu-item-padding-vertical)
|
|
136
|
+
var(--dropdown-menu-item-padding-horizontal);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
useDialogHotKeys,
|
|
17
17
|
useSearchFilter,
|
|
18
18
|
useRecentSearches,
|
|
19
|
+
useModalScrollLock,
|
|
19
20
|
} from '@redocly/theme/core/hooks';
|
|
20
21
|
import { Tag } from '@redocly/theme/components/Tag/Tag';
|
|
21
22
|
import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
|
|
@@ -75,7 +76,7 @@ export function SearchDialog({
|
|
|
75
76
|
} = useSearchFilter(filter, setFilter);
|
|
76
77
|
const { addSearchHistoryItem } = useRecentSearches();
|
|
77
78
|
const aiSearch = useAiSearch({ filter });
|
|
78
|
-
|
|
79
|
+
useModalScrollLock(true);
|
|
79
80
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
80
81
|
const modalRef = useRef<HTMLDivElement>(null);
|
|
81
82
|
|
|
@@ -4,6 +4,7 @@ import { useThemeHooks } from './use-theme-hooks';
|
|
|
4
4
|
import { IS_BROWSER } from '../utils/dom';
|
|
5
5
|
import { DEFAULT_MCP_SERVER_NAME } from '../constants';
|
|
6
6
|
import { generateMCPDeepLink } from '../utils/mcp';
|
|
7
|
+
import { withPathPrefix } from '../utils/urls';
|
|
7
8
|
|
|
8
9
|
export type McpConfig = {
|
|
9
10
|
serverName: string;
|
|
@@ -25,7 +26,7 @@ export function useMCPConfig(): McpConfig {
|
|
|
25
26
|
? window.location.origin
|
|
26
27
|
: ((globalThis as { SSR_HOSTNAME?: string })['SSR_HOSTNAME'] ?? '');
|
|
27
28
|
const serverName = name || DEFAULT_MCP_SERVER_NAME;
|
|
28
|
-
const serverUrl = `${origin}/mcp`;
|
|
29
|
+
const serverUrl = `${origin}${withPathPrefix('/mcp')}`;
|
|
29
30
|
const isMcpDisabled = !enabled || false;
|
|
30
31
|
|
|
31
32
|
const cursorUrl = useMemo(
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
export function useModalScrollLock(isOpen: boolean) {
|
|
3
|
+
export function useModalScrollLock(isOpen: boolean): void {
|
|
4
4
|
useEffect(() => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { body, documentElement } = document;
|
|
10
|
+
const originalOverflow = body.style.overflow;
|
|
11
|
+
const originalPaddingRight = body.style.paddingRight;
|
|
12
|
+
const originalScrollbarWidth =
|
|
13
|
+
documentElement.style.getPropertyValue('--modal-scrollbar-width');
|
|
14
|
+
|
|
15
|
+
const restoreScrollState = () => {
|
|
16
|
+
body.style.overflow = originalOverflow;
|
|
17
|
+
body.style.paddingRight = originalPaddingRight;
|
|
18
|
+
if (originalScrollbarWidth) {
|
|
19
|
+
documentElement.style.setProperty('--modal-scrollbar-width', originalScrollbarWidth);
|
|
20
|
+
} else {
|
|
21
|
+
documentElement.style.removeProperty('--modal-scrollbar-width');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
7
24
|
|
|
8
25
|
if (isOpen) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
26
|
+
const scrollbarWidth = window.innerWidth - documentElement.clientWidth;
|
|
27
|
+
|
|
28
|
+
body.style.overflow = 'hidden';
|
|
29
|
+
|
|
30
|
+
if (scrollbarWidth > 0) {
|
|
31
|
+
body.style.paddingRight = `${scrollbarWidth}px`;
|
|
32
|
+
documentElement.style.setProperty('--modal-scrollbar-width', `${scrollbarWidth}px`);
|
|
33
|
+
}
|
|
14
34
|
}
|
|
15
35
|
|
|
16
36
|
return () => {
|
|
17
|
-
|
|
18
|
-
document.body.style.marginRight = '';
|
|
37
|
+
restoreScrollState();
|
|
19
38
|
};
|
|
20
39
|
}, [isOpen]);
|
|
21
40
|
}
|
|
@@ -158,6 +158,7 @@ export function usePageActions(
|
|
|
158
158
|
action_type: 'view',
|
|
159
159
|
},
|
|
160
160
|
]);
|
|
161
|
+
window.location.href = mdPageUrl;
|
|
161
162
|
},
|
|
162
163
|
}),
|
|
163
164
|
|
|
@@ -165,12 +166,13 @@ export function usePageActions(
|
|
|
165
166
|
if (!isPublic) {
|
|
166
167
|
return null;
|
|
167
168
|
}
|
|
169
|
+
const link = getExternalAiPromptLink('https://chat.openai.com', mdPageUrl);
|
|
168
170
|
return {
|
|
169
171
|
buttonText: translate('page.actions.chatGptButtonText', 'Open in ChatGPT'),
|
|
170
172
|
title: translate('page.actions.chatGptTitle', 'Open in ChatGPT'),
|
|
171
173
|
description: translate('page.actions.chatGptDescription', 'Get insights from ChatGPT'),
|
|
172
174
|
iconComponent: ChatGptIcon,
|
|
173
|
-
link
|
|
175
|
+
link,
|
|
174
176
|
onClick: () => {
|
|
175
177
|
telemetry.sendPageActionsButtonClickedMessage([
|
|
176
178
|
{
|
|
@@ -178,6 +180,7 @@ export function usePageActions(
|
|
|
178
180
|
action_type: 'chatgpt',
|
|
179
181
|
},
|
|
180
182
|
]);
|
|
183
|
+
window.location.href = link;
|
|
181
184
|
},
|
|
182
185
|
};
|
|
183
186
|
},
|
|
@@ -186,12 +189,13 @@ export function usePageActions(
|
|
|
186
189
|
if (!isPublic) {
|
|
187
190
|
return null;
|
|
188
191
|
}
|
|
192
|
+
const link = getExternalAiPromptLink('https://claude.ai/new', mdPageUrl);
|
|
189
193
|
return {
|
|
190
194
|
buttonText: translate('page.actions.claudeButtonText', 'Open in Claude'),
|
|
191
195
|
title: translate('page.actions.claudeTitle', 'Open in Claude'),
|
|
192
196
|
description: translate('page.actions.claudeDescription', 'Get insights from Claude'),
|
|
193
197
|
iconComponent: ClaudeIcon,
|
|
194
|
-
link
|
|
198
|
+
link,
|
|
195
199
|
onClick: () => {
|
|
196
200
|
telemetry.sendPageActionsButtonClickedMessage([
|
|
197
201
|
{
|
|
@@ -199,6 +203,7 @@ export function usePageActions(
|
|
|
199
203
|
action_type: 'claude',
|
|
200
204
|
},
|
|
201
205
|
]);
|
|
206
|
+
window.location.href = link;
|
|
202
207
|
},
|
|
203
208
|
};
|
|
204
209
|
},
|
|
@@ -102,6 +102,12 @@ const HeadingContentWrapper = styled.div`
|
|
|
102
102
|
align-items: flex-start;
|
|
103
103
|
gap: var(--spacing-sm);
|
|
104
104
|
}
|
|
105
|
+
|
|
106
|
+
&:has([data-component-name='PageActions/PageActions']:hover) {
|
|
107
|
+
&& .anchor svg {
|
|
108
|
+
visibility: hidden;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
105
111
|
`;
|
|
106
112
|
|
|
107
113
|
const StyledHeadingText = styled.span`
|