@redocly/theme 0.71.0-next.0 → 0.71.0-next.2
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/Dropdown/DropdownMenuItem.d.ts +2 -2
- package/lib/components/Dropdown/DropdownMenuItem.js +3 -3
- package/lib/core/constants/search.js +6 -4
- package/lib/core/types/search.d.ts +1 -0
- package/lib/core/types/search.js +1 -0
- package/lib/core/utils/details.d.ts +5 -0
- package/lib/core/utils/details.js +11 -2
- package/lib/core/utils/search-ai-activity.js +5 -3
- package/lib/markdoc/tags/visibility.d.ts +15 -0
- package/lib/markdoc/tags/visibility.js +32 -0
- package/package.json +3 -2
- package/src/components/Dropdown/DropdownMenuItem.tsx +12 -5
- package/src/core/constants/search.ts +7 -4
- package/src/core/types/search.ts +1 -0
- package/src/core/utils/details.ts +9 -1
- package/src/core/utils/search-ai-activity.ts +5 -3
- package/src/markdoc/tags/visibility.ts +33 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CSSProperties, ReactNode, PropsWithChildren, JSX } from 'react';
|
|
1
|
+
import type { KeyboardEvent, MouseEvent, CSSProperties, ReactNode, PropsWithChildren, JSX } from 'react';
|
|
2
2
|
import type { LinkProps } from '../../core/types';
|
|
3
3
|
export type DropdownMenuItemProps = Partial<Pick<LinkProps, 'to' | 'target' | 'external'>> & {
|
|
4
4
|
prefix?: ReactNode;
|
|
@@ -12,7 +12,7 @@ export type DropdownMenuItemProps = Partial<Pick<LinkProps, 'to' | 'target' | 'e
|
|
|
12
12
|
separator?: boolean;
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
dangerous?: boolean;
|
|
15
|
-
onAction?: () => void;
|
|
15
|
+
onAction?: (event: KeyboardEvent | MouseEvent) => void;
|
|
16
16
|
active?: boolean;
|
|
17
17
|
};
|
|
18
18
|
export declare function DropdownMenuItem({ children, content, active, onAction, to, dangerous, prefix, suffix, disabled, separator, dataAttributes, className, separatorLine, style, role, ...otherProps }: PropsWithChildren<DropdownMenuItemProps>): JSX.Element;
|
|
@@ -53,12 +53,12 @@ const styled_components_1 = __importStar(require("styled-components"));
|
|
|
53
53
|
const Link_1 = require("../../components/Link/Link");
|
|
54
54
|
function DropdownMenuItem(_a) {
|
|
55
55
|
var { children, content, active, onAction, to, dangerous, prefix, suffix, disabled, separator, dataAttributes, className, separatorLine, style, role = 'menuitem' } = _a, otherProps = __rest(_a, ["children", "content", "active", "onAction", "to", "dangerous", "prefix", "suffix", "disabled", "separator", "dataAttributes", "className", "separatorLine", "style", "role"]);
|
|
56
|
-
const handleClick = () => {
|
|
57
|
-
onAction === null || onAction === void 0 ? void 0 : onAction();
|
|
56
|
+
const handleClick = (event) => {
|
|
57
|
+
onAction === null || onAction === void 0 ? void 0 : onAction(event);
|
|
58
58
|
};
|
|
59
59
|
const handleKeyDown = (event) => {
|
|
60
60
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
61
|
-
onAction === null || onAction === void 0 ? void 0 : onAction();
|
|
61
|
+
onAction === null || onAction === void 0 ? void 0 : onAction(event);
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
className = className || '' + (active ? ' active' : '');
|
|
@@ -40,6 +40,10 @@ exports.AI_SEARCH_ERROR_CONFIG = {
|
|
|
40
40
|
exports.AI_SEARCH_MAX_MESSAGE_LENGTH = 45000;
|
|
41
41
|
exports.SEARCH_DEBOUNCE_TIME_MS = 500;
|
|
42
42
|
exports.DEFAULT_KEYBOARD_SHORTCUTS = '⌘+K,CTRL+K';
|
|
43
|
+
const discoverToolsDisplayText = {
|
|
44
|
+
inProgressText: 'Discovering available tools...',
|
|
45
|
+
completedText: 'Discovered available tools',
|
|
46
|
+
};
|
|
43
47
|
exports.TOOL_CALL_DISPLAY_TEXT = {
|
|
44
48
|
[search_1.ToolCallName.SearchDocumentation]: {
|
|
45
49
|
inProgressText: 'Searching documentation...',
|
|
@@ -69,10 +73,8 @@ exports.TOOL_CALL_DISPLAY_TEXT = {
|
|
|
69
73
|
inProgressText: 'Running code...',
|
|
70
74
|
completedText: 'Ran code',
|
|
71
75
|
},
|
|
72
|
-
[search_1.ToolCallName.DescribeTools]:
|
|
73
|
-
|
|
74
|
-
completedText: 'Discovered available tools',
|
|
75
|
-
},
|
|
76
|
+
[search_1.ToolCallName.DescribeTools]: discoverToolsDisplayText,
|
|
77
|
+
[search_1.ToolCallName.Discover]: discoverToolsDisplayText,
|
|
76
78
|
[search_1.ToolCallName.ContactSupport]: {
|
|
77
79
|
inProgressText: 'Opening the contact support option...',
|
|
78
80
|
completedText: 'Offered to contact support',
|
package/lib/core/types/search.js
CHANGED
|
@@ -16,6 +16,7 @@ var ToolCallName;
|
|
|
16
16
|
ToolCallName["GetFullApiDescription"] = "get-full-api-description";
|
|
17
17
|
ToolCallName["Execute"] = "execute";
|
|
18
18
|
ToolCallName["DescribeTools"] = "describe-tools";
|
|
19
|
+
ToolCallName["Discover"] = "discover";
|
|
19
20
|
ToolCallName["ContactSupport"] = "contact-support";
|
|
20
21
|
})(ToolCallName || (exports.ToolCallName = ToolCallName = {}));
|
|
21
22
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1,6 @@
|
|
|
1
1
|
export declare function extendDetailsBehaviour(): () => void;
|
|
2
|
+
/**
|
|
3
|
+
* The id a `<details>` element without one gets from its summary text; a URL hash with that id
|
|
4
|
+
* opens it. Empty for an empty summary.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detailsAnchorId(summaryText: string): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extendDetailsBehaviour = extendDetailsBehaviour;
|
|
4
|
+
exports.detailsAnchorId = detailsAnchorId;
|
|
4
5
|
function extendDetailsBehaviour() {
|
|
5
6
|
enhanceDetails();
|
|
6
7
|
openDetailsFromHash();
|
|
@@ -9,6 +10,13 @@ function extendDetailsBehaviour() {
|
|
|
9
10
|
window.removeEventListener('hashchange', openDetailsFromHash);
|
|
10
11
|
};
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* The id a `<details>` element without one gets from its summary text; a URL hash with that id
|
|
15
|
+
* opens it. Empty for an empty summary.
|
|
16
|
+
*/
|
|
17
|
+
function detailsAnchorId(summaryText) {
|
|
18
|
+
return summaryText.replace(/\s+/g, '-').toLowerCase();
|
|
19
|
+
}
|
|
12
20
|
function openDetailsAndScroll(detailsElement) {
|
|
13
21
|
detailsElement.setAttribute('open', '');
|
|
14
22
|
setTimeout(() => {
|
|
@@ -21,11 +29,12 @@ function openDetailsAndScroll(detailsElement) {
|
|
|
21
29
|
function enhanceDetails() {
|
|
22
30
|
const existingIds = [];
|
|
23
31
|
Array.from(document.getElementsByTagName('details')).forEach((detailsElement, index) => {
|
|
24
|
-
var _a
|
|
32
|
+
var _a;
|
|
33
|
+
var _b;
|
|
25
34
|
if (detailsElement.id) {
|
|
26
35
|
return;
|
|
27
36
|
}
|
|
28
|
-
const generatedId = ((_b = (_a = detailsElement.querySelector('summary')) === null || _a === void 0 ? void 0 : _a.textContent)
|
|
37
|
+
const generatedId = detailsAnchorId((_b = (_a = detailsElement.querySelector('summary')) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : '') ||
|
|
29
38
|
`details-${index}`;
|
|
30
39
|
detailsElement.id = existingIds.includes(generatedId) ? `${generatedId}-${index}` : generatedId;
|
|
31
40
|
existingIds.push(detailsElement.id);
|
|
@@ -40,10 +40,10 @@ function getSearchAiActivityStep(toolCall, isRunning, translate) {
|
|
|
40
40
|
}
|
|
41
41
|
function getToolCallLabel(toolCall, isCompleted, translate) {
|
|
42
42
|
const detail = getToolCallDetail(toolCall);
|
|
43
|
-
|
|
43
|
+
const builtInText = search_2.TOOL_CALL_DISPLAY_TEXT[toolCall.name];
|
|
44
|
+
if ((toolCall.name === search_1.ToolCallName.Execute || !builtInText) && detail) {
|
|
44
45
|
return { label: detail };
|
|
45
46
|
}
|
|
46
|
-
const builtInText = search_2.TOOL_CALL_DISPLAY_TEXT[toolCall.name];
|
|
47
47
|
if (builtInText) {
|
|
48
48
|
const text = isCompleted ? builtInText.completedText : builtInText.inProgressText;
|
|
49
49
|
return detail ? { label: stripEllipsis(text), detail } : { label: text };
|
|
@@ -67,7 +67,9 @@ function getToolCallDetail(toolCall) {
|
|
|
67
67
|
case search_1.ToolCallName.Execute:
|
|
68
68
|
return getStringArg(toolCall.args, 'description');
|
|
69
69
|
default:
|
|
70
|
-
return
|
|
70
|
+
return search_2.TOOL_CALL_DISPLAY_TEXT[toolCall.name]
|
|
71
|
+
? undefined
|
|
72
|
+
: getStringArg(toolCall.args, 'description');
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
function getStringArg(args, name) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
|
|
2
|
+
/** The part of a node the check reads; a stored plain-JSON AST node satisfies it too. */
|
|
3
|
+
type VisibilityNodeLike = {
|
|
4
|
+
tag?: string;
|
|
5
|
+
attributes?: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
/** True for a node whose content must never reach the rendered page. */
|
|
8
|
+
export declare function isForAgentsOnly(node: VisibilityNodeLike): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* A `renderTag` that empties nodes hidden from the page and leaves every other tag to the
|
|
11
|
+
* caller's own walk. Used by the text extractors that read a raw AST, which no tag schema runs on.
|
|
12
|
+
*/
|
|
13
|
+
export declare function skipAgentsOnlyContent(node: VisibilityNodeLike): string | undefined;
|
|
14
|
+
export declare const visibility: MarkdocSchemaWrapper;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.visibility = void 0;
|
|
4
|
+
exports.isForAgentsOnly = isForAgentsOnly;
|
|
5
|
+
exports.skipAgentsOnlyContent = skipAgentsOnlyContent;
|
|
6
|
+
/** True for a node whose content must never reach the rendered page. */
|
|
7
|
+
function isForAgentsOnly(node) {
|
|
8
|
+
var _a;
|
|
9
|
+
return node.tag === 'visibility' && ((_a = node.attributes) === null || _a === void 0 ? void 0 : _a.for) === 'agents';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A `renderTag` that empties nodes hidden from the page and leaves every other tag to the
|
|
13
|
+
* caller's own walk. Used by the text extractors that read a raw AST, which no tag schema runs on.
|
|
14
|
+
*/
|
|
15
|
+
function skipAgentsOnlyContent(node) {
|
|
16
|
+
return isForAgentsOnly(node) ? '' : undefined;
|
|
17
|
+
}
|
|
18
|
+
exports.visibility = {
|
|
19
|
+
schema: {
|
|
20
|
+
attributes: {
|
|
21
|
+
for: { type: String, required: true, matches: ['humans', 'agents'] },
|
|
22
|
+
},
|
|
23
|
+
transform(node, config) {
|
|
24
|
+
return isForAgentsOnly(node) ? [] : node.transformChildren(config);
|
|
25
|
+
},
|
|
26
|
+
renderForLlms(node, { getBody }) {
|
|
27
|
+
return node.attributes.for === 'humans' ? '' : getBody();
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
tagName: 'visibility',
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=visibility.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.71.0-next.
|
|
3
|
+
"version": "0.71.0-next.2",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"./core/templates/*": "./lib/core/templates/*.js",
|
|
23
23
|
"./core/contexts/*": "./lib/core/contexts/*.js",
|
|
24
24
|
"./core/hooks/*": "./lib/core/hooks/*.js",
|
|
25
|
+
"./core/utils/*": "./lib/core/utils/*.js",
|
|
25
26
|
"./core/hoc/*": "./lib/core/hoc/*.js",
|
|
26
27
|
"./core/constants/*": "./lib/core/constants/*.js",
|
|
27
28
|
"./ext/*": "./lib/ext/*.js",
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
"webpack": "5.105.2"
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
71
|
-
"@redocly/config": "0.
|
|
72
|
+
"@redocly/config": "0.66.0",
|
|
72
73
|
"@tanstack/react-query": "5.62.3",
|
|
73
74
|
"@tanstack/react-virtual": "3.13.0",
|
|
74
75
|
"@xyflow/react": "12.8.3",
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
KeyboardEvent,
|
|
6
|
+
MouseEvent,
|
|
7
|
+
CSSProperties,
|
|
8
|
+
ReactNode,
|
|
9
|
+
PropsWithChildren,
|
|
10
|
+
JSX,
|
|
11
|
+
} from 'react';
|
|
5
12
|
import type { LinkProps } from '@redocly/theme/core/types';
|
|
6
13
|
|
|
7
14
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
@@ -21,7 +28,7 @@ export type DropdownMenuItemProps = Partial<Pick<LinkProps, 'to' | 'target' | 'e
|
|
|
21
28
|
separator?: boolean;
|
|
22
29
|
disabled?: boolean;
|
|
23
30
|
dangerous?: boolean;
|
|
24
|
-
onAction?: () => void;
|
|
31
|
+
onAction?: (event: KeyboardEvent | MouseEvent) => void;
|
|
25
32
|
active?: boolean;
|
|
26
33
|
};
|
|
27
34
|
|
|
@@ -43,13 +50,13 @@ export function DropdownMenuItem({
|
|
|
43
50
|
role = 'menuitem',
|
|
44
51
|
...otherProps
|
|
45
52
|
}: PropsWithChildren<DropdownMenuItemProps>): JSX.Element {
|
|
46
|
-
const handleClick = () => {
|
|
47
|
-
onAction?.();
|
|
53
|
+
const handleClick = (event: MouseEvent) => {
|
|
54
|
+
onAction?.(event);
|
|
48
55
|
};
|
|
49
56
|
|
|
50
57
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
51
58
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
52
|
-
onAction?.();
|
|
59
|
+
onAction?.(event);
|
|
53
60
|
}
|
|
54
61
|
};
|
|
55
62
|
|
|
@@ -48,6 +48,11 @@ export const SEARCH_DEBOUNCE_TIME_MS = 500;
|
|
|
48
48
|
|
|
49
49
|
export const DEFAULT_KEYBOARD_SHORTCUTS = '⌘+K,CTRL+K';
|
|
50
50
|
|
|
51
|
+
const discoverToolsDisplayText = {
|
|
52
|
+
inProgressText: 'Discovering available tools...',
|
|
53
|
+
completedText: 'Discovered available tools',
|
|
54
|
+
};
|
|
55
|
+
|
|
51
56
|
export const TOOL_CALL_DISPLAY_TEXT: Partial<
|
|
52
57
|
Record<string, { inProgressText: string; completedText: string }>
|
|
53
58
|
> = {
|
|
@@ -79,10 +84,8 @@ export const TOOL_CALL_DISPLAY_TEXT: Partial<
|
|
|
79
84
|
inProgressText: 'Running code...',
|
|
80
85
|
completedText: 'Ran code',
|
|
81
86
|
},
|
|
82
|
-
[ToolCallName.DescribeTools]:
|
|
83
|
-
|
|
84
|
-
completedText: 'Discovered available tools',
|
|
85
|
-
},
|
|
87
|
+
[ToolCallName.DescribeTools]: discoverToolsDisplayText,
|
|
88
|
+
[ToolCallName.Discover]: discoverToolsDisplayText,
|
|
86
89
|
[ToolCallName.ContactSupport]: {
|
|
87
90
|
inProgressText: 'Opening the contact support option...',
|
|
88
91
|
completedText: 'Offered to contact support',
|
package/src/core/types/search.ts
CHANGED
|
@@ -8,6 +8,14 @@ export function extendDetailsBehaviour() {
|
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* The id a `<details>` element without one gets from its summary text; a URL hash with that id
|
|
13
|
+
* opens it. Empty for an empty summary.
|
|
14
|
+
*/
|
|
15
|
+
export function detailsAnchorId(summaryText: string): string {
|
|
16
|
+
return summaryText.replace(/\s+/g, '-').toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
function openDetailsAndScroll(detailsElement: Element) {
|
|
12
20
|
detailsElement.setAttribute('open', '');
|
|
13
21
|
setTimeout(() => {
|
|
@@ -26,7 +34,7 @@ function enhanceDetails() {
|
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
const generatedId =
|
|
29
|
-
detailsElement.querySelector('summary')?.textContent
|
|
37
|
+
detailsAnchorId(detailsElement.querySelector('summary')?.textContent ?? '') ||
|
|
30
38
|
`details-${index}`;
|
|
31
39
|
|
|
32
40
|
detailsElement.id = existingIds.includes(generatedId) ? `${generatedId}-${index}` : generatedId;
|
|
@@ -66,10 +66,10 @@ function getToolCallLabel(
|
|
|
66
66
|
translate: TFunction,
|
|
67
67
|
): { label: string; detail?: string } {
|
|
68
68
|
const detail = getToolCallDetail(toolCall);
|
|
69
|
-
|
|
69
|
+
const builtInText = TOOL_CALL_DISPLAY_TEXT[toolCall.name];
|
|
70
|
+
if ((toolCall.name === ToolCallName.Execute || !builtInText) && detail) {
|
|
70
71
|
return { label: detail };
|
|
71
72
|
}
|
|
72
|
-
const builtInText = TOOL_CALL_DISPLAY_TEXT[toolCall.name];
|
|
73
73
|
if (builtInText) {
|
|
74
74
|
const text = isCompleted ? builtInText.completedText : builtInText.inProgressText;
|
|
75
75
|
return detail ? { label: stripEllipsis(text), detail } : { label: text };
|
|
@@ -93,7 +93,9 @@ function getToolCallDetail(toolCall: ToolCall): string | undefined {
|
|
|
93
93
|
case ToolCallName.Execute:
|
|
94
94
|
return getStringArg(toolCall.args, 'description');
|
|
95
95
|
default:
|
|
96
|
-
return
|
|
96
|
+
return TOOL_CALL_DISPLAY_TEXT[toolCall.name]
|
|
97
|
+
? undefined
|
|
98
|
+
: getStringArg(toolCall.args, 'description');
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Config, Node } from '@markdoc/markdoc';
|
|
2
|
+
import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
|
|
3
|
+
|
|
4
|
+
/** The part of a node the check reads; a stored plain-JSON AST node satisfies it too. */
|
|
5
|
+
type VisibilityNodeLike = { tag?: string; attributes?: Record<string, unknown> };
|
|
6
|
+
|
|
7
|
+
/** True for a node whose content must never reach the rendered page. */
|
|
8
|
+
export function isForAgentsOnly(node: VisibilityNodeLike): boolean {
|
|
9
|
+
return node.tag === 'visibility' && node.attributes?.for === 'agents';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A `renderTag` that empties nodes hidden from the page and leaves every other tag to the
|
|
14
|
+
* caller's own walk. Used by the text extractors that read a raw AST, which no tag schema runs on.
|
|
15
|
+
*/
|
|
16
|
+
export function skipAgentsOnlyContent(node: VisibilityNodeLike): string | undefined {
|
|
17
|
+
return isForAgentsOnly(node) ? '' : undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const visibility: MarkdocSchemaWrapper = {
|
|
21
|
+
schema: {
|
|
22
|
+
attributes: {
|
|
23
|
+
for: { type: String, required: true, matches: ['humans', 'agents'] },
|
|
24
|
+
},
|
|
25
|
+
transform(node: Node, config: Config) {
|
|
26
|
+
return isForAgentsOnly(node) ? [] : node.transformChildren(config);
|
|
27
|
+
},
|
|
28
|
+
renderForLlms(node: Node, { getBody }) {
|
|
29
|
+
return node.attributes.for === 'humans' ? '' : getBody();
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
tagName: 'visibility',
|
|
33
|
+
};
|