@redocly/theme 0.70.0-next.8 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/lib/components/LoadProgressBar/LoadProgressBar.d.ts +8 -0
  2. package/lib/components/LoadProgressBar/LoadProgressBar.js +122 -0
  3. package/lib/core/constants/index.d.ts +1 -0
  4. package/lib/core/constants/index.js +1 -0
  5. package/lib/core/constants/prompt.d.ts +9 -0
  6. package/lib/core/constants/prompt.js +33 -0
  7. package/lib/core/hooks/index.d.ts +3 -0
  8. package/lib/core/hooks/index.js +3 -0
  9. package/lib/core/hooks/prompt/use-prompt-actions.d.ts +7 -0
  10. package/lib/core/hooks/prompt/use-prompt-actions.js +19 -0
  11. package/lib/core/hooks/prompt/use-prompt-text-limit.d.ts +19 -0
  12. package/lib/core/hooks/prompt/use-prompt-text-limit.js +35 -0
  13. package/lib/core/hooks/use-page-actions.js +4 -8
  14. package/lib/core/hooks/use-pointer-border-highlight.d.ts +7 -0
  15. package/lib/core/hooks/use-pointer-border-highlight.js +29 -0
  16. package/lib/core/hooks/use-telemetry-fallback.d.ts +2 -0
  17. package/lib/core/hooks/use-telemetry-fallback.js +2 -0
  18. package/lib/core/styles/dark.js +14 -12
  19. package/lib/core/styles/global.js +16 -54
  20. package/lib/core/types/index.d.ts +1 -0
  21. package/lib/core/types/l10n.d.ts +1 -1
  22. package/lib/core/types/prompt.d.ts +9 -0
  23. package/lib/core/types/prompt.js +3 -0
  24. package/lib/core/utils/get-ai-prompt-link.d.ts +15 -0
  25. package/lib/core/utils/get-ai-prompt-link.js +29 -0
  26. package/lib/core/utils/index.d.ts +1 -0
  27. package/lib/core/utils/index.js +1 -0
  28. package/lib/core/utils/urls.js +1 -1
  29. package/lib/core/utils/with-load-progress.d.ts +3 -0
  30. package/lib/core/utils/with-load-progress.js +24 -19
  31. package/lib/ext/configure.d.ts +1 -1
  32. package/lib/ext/configure.js +0 -1
  33. package/lib/icons/LinkIcon/LinkIconSymbol.d.ts +12 -0
  34. package/lib/icons/LinkIcon/LinkIconSymbol.js +41 -0
  35. package/lib/index.d.ts +1 -0
  36. package/lib/index.js +1 -0
  37. package/lib/markdoc/components/Cards/Card.js +1 -1
  38. package/lib/markdoc/components/Prompt/Prompt.d.ts +15 -0
  39. package/lib/markdoc/components/Prompt/Prompt.js +163 -0
  40. package/lib/markdoc/components/Prompt/PromptActions.d.ts +13 -0
  41. package/lib/markdoc/components/Prompt/PromptActions.js +43 -0
  42. package/lib/markdoc/components/Prompt/PromptBody.d.ts +14 -0
  43. package/lib/markdoc/components/Prompt/PromptBody.js +99 -0
  44. package/lib/markdoc/components/Prompt/PromptCopyButton.d.ts +10 -0
  45. package/lib/markdoc/components/Prompt/PromptCopyButton.js +28 -0
  46. package/lib/markdoc/components/Prompt/PromptHeader.d.ts +9 -0
  47. package/lib/markdoc/components/Prompt/PromptHeader.js +57 -0
  48. package/lib/markdoc/components/Prompt/PromptShowHideButton.d.ts +7 -0
  49. package/lib/markdoc/components/Prompt/PromptShowHideButton.js +21 -0
  50. package/lib/markdoc/components/Prompt/PromptToggleLabel.d.ts +7 -0
  51. package/lib/markdoc/components/Prompt/PromptToggleLabel.js +28 -0
  52. package/lib/markdoc/components/Prompt/variables.d.ts +1 -0
  53. package/lib/markdoc/components/Prompt/variables.dark.d.ts +1 -0
  54. package/lib/markdoc/components/Prompt/variables.dark.js +8 -0
  55. package/lib/markdoc/components/Prompt/variables.js +44 -0
  56. package/lib/markdoc/components/default.d.ts +1 -0
  57. package/lib/markdoc/components/default.js +1 -0
  58. package/lib/markdoc/default.d.ts +2 -0
  59. package/lib/markdoc/default.js +2 -0
  60. package/lib/markdoc/tags/code-walkthrough.d.ts +1 -1
  61. package/lib/markdoc/tags/code-walkthrough.js +3 -5
  62. package/lib/markdoc/tags/prompt.d.ts +2 -0
  63. package/lib/markdoc/tags/prompt.js +56 -0
  64. package/package.json +2 -7
  65. package/src/components/LoadProgressBar/LoadProgressBar.tsx +113 -0
  66. package/src/core/constants/index.ts +1 -0
  67. package/src/core/constants/prompt.ts +34 -0
  68. package/src/core/hooks/__mocks__/index.ts +3 -0
  69. package/src/core/hooks/__mocks__/use-theme-hooks.ts +2 -0
  70. package/src/core/hooks/index.ts +3 -0
  71. package/src/core/hooks/prompt/use-prompt-actions.ts +28 -0
  72. package/src/core/hooks/prompt/use-prompt-text-limit.ts +59 -0
  73. package/src/core/hooks/use-page-actions.ts +4 -9
  74. package/src/core/hooks/use-pointer-border-highlight.ts +46 -0
  75. package/src/core/hooks/use-telemetry-fallback.ts +2 -0
  76. package/src/core/styles/dark.ts +2 -0
  77. package/src/core/styles/global.ts +2 -40
  78. package/src/core/types/index.ts +1 -0
  79. package/src/core/types/l10n.ts +11 -0
  80. package/src/core/types/prompt.ts +11 -0
  81. package/src/core/utils/get-ai-prompt-link.ts +30 -0
  82. package/src/core/utils/index.ts +1 -0
  83. package/src/core/utils/urls.ts +1 -1
  84. package/src/core/utils/with-load-progress.ts +23 -18
  85. package/src/ext/configure.ts +1 -1
  86. package/src/icons/LinkIcon/LinkIconSymbol.tsx +51 -0
  87. package/src/index.ts +1 -0
  88. package/src/markdoc/components/Cards/Card.tsx +1 -1
  89. package/src/markdoc/components/Prompt/Prompt.tsx +219 -0
  90. package/src/markdoc/components/Prompt/PromptActions.tsx +104 -0
  91. package/src/markdoc/components/Prompt/PromptBody.tsx +107 -0
  92. package/src/markdoc/components/Prompt/PromptCopyButton.tsx +73 -0
  93. package/src/markdoc/components/Prompt/PromptHeader.tsx +81 -0
  94. package/src/markdoc/components/Prompt/PromptShowHideButton.tsx +43 -0
  95. package/src/markdoc/components/Prompt/PromptToggleLabel.tsx +41 -0
  96. package/src/markdoc/components/Prompt/variables.dark.ts +5 -0
  97. package/src/markdoc/components/Prompt/variables.ts +41 -0
  98. package/src/markdoc/components/default.ts +1 -0
  99. package/src/markdoc/default.ts +2 -0
  100. package/src/markdoc/tags/code-walkthrough.ts +4 -12
  101. package/src/markdoc/tags/prompt.ts +58 -0
@@ -0,0 +1,99 @@
1
+ "use strict";
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
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PromptBody = PromptBody;
40
+ const react_1 = __importDefault(require("react"));
41
+ const styled_components_1 = __importStar(require("styled-components"));
42
+ const Button_1 = require("../../../components/Button/Button");
43
+ const ChevronDownIcon_1 = require("../../../icons/ChevronDownIcon/ChevronDownIcon");
44
+ const ChevronUpIcon_1 = require("../../../icons/ChevronUpIcon/ChevronUpIcon");
45
+ const hooks_1 = require("../../../core/hooks");
46
+ function PromptBody({ prompt, textRef, textLimit, isExpanded, hasHiddenText, onToggleExpanded, controls, className, }) {
47
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
48
+ const { translate } = useTranslate();
49
+ return (react_1.default.createElement(PromptBodyWrapper, { "data-component-name": "Markdoc/Prompt/PromptBody", className: className },
50
+ react_1.default.createElement(ZoneWrapper, null,
51
+ react_1.default.createElement(TextWrapper, { ref: textRef, $textLimit: textLimit }, prompt),
52
+ controls),
53
+ hasHiddenText || isExpanded ? (react_1.default.createElement(Button_1.Button, { variant: "ghost", size: "small", icon: isExpanded ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null), iconPosition: "right", onClick: onToggleExpanded }, isExpanded
54
+ ? translate('promptTag.showLess', 'Show less')
55
+ : translate('promptTag.showFullPrompt', 'Show full prompt'))) : null));
56
+ }
57
+ const PromptBodyWrapper = styled_components_1.default.div `
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: flex-start;
61
+ gap: var(--prompt-body-toggle-gap);
62
+ `;
63
+ const ZoneWrapper = styled_components_1.default.div `
64
+ display: flex;
65
+ align-items: flex-start;
66
+ width: 100%;
67
+ gap: var(--prompt-body-gap);
68
+ padding: var(--prompt-body-padding-vertical) var(--prompt-body-padding-horizontal);
69
+ background-color: var(--prompt-body-bg-color);
70
+ border-radius: var(--prompt-body-border-radius);
71
+ `;
72
+ /* width: 0 keeps the nowrap text from widening the block; flex-grow gives the text the real width. */
73
+ const TextWrapper = styled_components_1.default.div `
74
+ flex: 1 1 0;
75
+ width: 0;
76
+ min-width: 0;
77
+ white-space: pre-wrap;
78
+ overflow: visible;
79
+ overflow-wrap: anywhere;
80
+ font-size: var(--prompt-body-font-size);
81
+ line-height: var(--prompt-body-line-height);
82
+ color: var(--prompt-body-text-color);
83
+
84
+ ${({ $textLimit }) => $textLimit === 'maxLines' &&
85
+ (0, styled_components_1.css) `
86
+ display: -webkit-box;
87
+ -webkit-box-orient: vertical;
88
+ -webkit-line-clamp: var(--prompt-body-max-lines);
89
+ overflow: hidden;
90
+ `}
91
+
92
+ ${({ $textLimit }) => $textLimit === 'oneLine' &&
93
+ (0, styled_components_1.css) `
94
+ white-space: nowrap;
95
+ overflow: hidden;
96
+ text-overflow: ellipsis;
97
+ `}
98
+ `;
99
+ //# sourceMappingURL=PromptBody.js.map
@@ -0,0 +1,10 @@
1
+ import type { JSX } from 'react';
2
+ export type PromptCopyButtonPlacement = 'header' | 'body' | 'standalone';
3
+ export type PromptCopyButtonProps = {
4
+ prompt: string;
5
+ /** `header` next to the split button, `body` inside the prompt zone, `standalone` for the button-only variant. */
6
+ placement: PromptCopyButtonPlacement;
7
+ onCopy: () => void;
8
+ className?: string;
9
+ };
10
+ export declare function PromptCopyButton({ prompt, placement, onCopy, className, }: PromptCopyButtonProps): JSX.Element;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PromptCopyButton = PromptCopyButton;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const CopyButton_1 = require("../../../components/Buttons/CopyButton");
10
+ const hooks_1 = require("../../../core/hooks");
11
+ function PromptCopyButton({ prompt, placement, onCopy, className, }) {
12
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
13
+ const { translate } = useTranslate();
14
+ if (placement === 'standalone') {
15
+ return (react_1.default.createElement(CopyButton_1.CopyButton, { data: prompt, type: "compound", variant: "secondary", size: "small", buttonText: translate('promptTag.copy.buttonText', 'Copy prompt'), onCopyClick: onCopy, dataTestId: "prompt-copy-button", className: className }));
16
+ }
17
+ if (placement === 'header') {
18
+ return (react_1.default.createElement(HeaderCopyButtonWrapper, { data: prompt, variant: "outlined", size: "small", onCopyClick: onCopy, dataTestId: "prompt-header-copy-button", className: className }));
19
+ }
20
+ return (react_1.default.createElement(CopyButton_1.CopyButton, { data: prompt, variant: "text", size: "small", onCopyClick: onCopy, dataTestId: "prompt-copy-button", className: className }));
21
+ }
22
+ /* The outlined border adds to the box; the smaller padding keeps the 24px height of the sibling buttons. */
23
+ const HeaderCopyButtonWrapper = (0, styled_components_1.default)(CopyButton_1.CopyButton) `
24
+ && .button {
25
+ --button-icon-padding: var(--prompt-header-copy-button-padding);
26
+ }
27
+ `;
28
+ //# sourceMappingURL=PromptCopyButton.js.map
@@ -0,0 +1,9 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ export type PromptHeaderProps = {
3
+ title?: string;
4
+ icon?: string;
5
+ iconRawContent?: string;
6
+ controls?: ReactNode;
7
+ className?: string;
8
+ };
9
+ export declare function PromptHeader({ title, icon, iconRawContent, controls, className, }: PromptHeaderProps): JSX.Element;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PromptHeader = PromptHeader;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const AiStarsIcon_1 = require("../../../icons/AiStarsIcon/AiStarsIcon");
10
+ const GenericIcon_1 = require("../../../icons/GenericIcon/GenericIcon");
11
+ function PromptHeader({ title, icon, iconRawContent, controls, className, }) {
12
+ return (react_1.default.createElement(PromptHeaderWrapper, { "data-component-name": "Markdoc/Prompt/PromptHeader", className: className },
13
+ react_1.default.createElement(IconWrapper, null, icon ? (react_1.default.createElement(GenericIcon_1.GenericIcon, { icon: icon, rawContent: iconRawContent })) : (react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { color: "--prompt-icon-color" }))),
14
+ title ? react_1.default.createElement(TitleWrapper, null, title) : null,
15
+ controls ? react_1.default.createElement(ControlsWrapper, null, controls) : null));
16
+ }
17
+ const PromptHeaderWrapper = styled_components_1.default.div `
18
+ display: flex;
19
+ align-items: center;
20
+ gap: var(--prompt-header-gap);
21
+ `;
22
+ const IconWrapper = styled_components_1.default.div `
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ flex-shrink: 0;
27
+ width: var(--prompt-icon-size);
28
+ height: var(--prompt-icon-size);
29
+ color: var(--prompt-icon-color);
30
+ --icon-width: var(--prompt-icon-size);
31
+ --icon-height: var(--prompt-icon-size);
32
+ --icon-color: var(--prompt-icon-color);
33
+
34
+ svg {
35
+ width: 100%;
36
+ height: 100%;
37
+ }
38
+ `;
39
+ const TitleWrapper = styled_components_1.default.div `
40
+ flex: 1;
41
+ min-width: 0;
42
+ overflow: hidden;
43
+ text-overflow: ellipsis;
44
+ white-space: nowrap;
45
+ font-size: var(--prompt-title-font-size);
46
+ font-weight: var(--prompt-title-font-weight);
47
+ line-height: var(--prompt-title-line-height);
48
+ color: var(--prompt-title-text-color);
49
+ `;
50
+ const ControlsWrapper = styled_components_1.default.div `
51
+ display: flex;
52
+ align-items: center;
53
+ flex-shrink: 0;
54
+ margin-left: auto;
55
+ gap: var(--prompt-header-actions-gap);
56
+ `;
57
+ //# sourceMappingURL=PromptHeader.js.map
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ export type PromptShowHideButtonProps = {
3
+ isPromptVisible: boolean;
4
+ onToggle: () => void;
5
+ className?: string;
6
+ };
7
+ export declare function PromptShowHideButton({ isPromptVisible, onToggle, className, }: PromptShowHideButtonProps): JSX.Element;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PromptShowHideButton = PromptShowHideButton;
7
+ const react_1 = __importDefault(require("react"));
8
+ const Button_1 = require("../../../components/Button/Button");
9
+ const ChevronDownIcon_1 = require("../../../icons/ChevronDownIcon/ChevronDownIcon");
10
+ const ChevronUpIcon_1 = require("../../../icons/ChevronUpIcon/ChevronUpIcon");
11
+ const hooks_1 = require("../../../core/hooks");
12
+ const PromptToggleLabel_1 = require("../../../markdoc/components/Prompt/PromptToggleLabel");
13
+ function PromptShowHideButton({ isPromptVisible, onToggle, className, }) {
14
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
15
+ const { translate } = useTranslate();
16
+ const showPromptLabel = translate('promptTag.showPrompt', 'Show prompt');
17
+ const hidePromptLabel = translate('promptTag.hidePrompt', 'Hide prompt');
18
+ return (react_1.default.createElement(Button_1.Button, { "data-component-name": "Markdoc/Prompt/PromptShowHideButton", className: className, variant: "text", size: "small", icon: isPromptVisible ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null), iconPosition: "right", onClick: onToggle },
19
+ react_1.default.createElement(PromptToggleLabel_1.PromptToggleLabel, { active: isPromptVisible ? hidePromptLabel : showPromptLabel, inactive: isPromptVisible ? showPromptLabel : hidePromptLabel })));
20
+ }
21
+ //# sourceMappingURL=PromptShowHideButton.js.map
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ export type PromptToggleLabelProps = {
3
+ active: string;
4
+ inactive: string;
5
+ className?: string;
6
+ };
7
+ export declare function PromptToggleLabel({ active, inactive, className, }: PromptToggleLabelProps): JSX.Element;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PromptToggleLabel = PromptToggleLabel;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ /* Both labels share one grid cell, so the toggle keeps the width of the longer label
10
+ and the buttons next to it do not move when the label changes. */
11
+ function PromptToggleLabel({ active, inactive, className, }) {
12
+ return (react_1.default.createElement(PromptToggleLabelWrapper, { "data-component-name": "Markdoc/Prompt/PromptToggleLabel", className: className },
13
+ react_1.default.createElement("span", null, active),
14
+ react_1.default.createElement("span", { "aria-hidden": "true" }, inactive)));
15
+ }
16
+ const PromptToggleLabelWrapper = styled_components_1.default.span `
17
+ display: grid;
18
+ text-align: center;
19
+
20
+ > span {
21
+ grid-area: 1 / 1;
22
+ }
23
+
24
+ > span[aria-hidden='true'] {
25
+ visibility: hidden;
26
+ }
27
+ `;
28
+ //# sourceMappingURL=PromptToggleLabel.js.map
@@ -0,0 +1 @@
1
+ export declare const promptTag: import("styled-components").RuleSet<object>;
@@ -0,0 +1 @@
1
+ export declare const promptTagDarkMode: import("styled-components").RuleSet<object>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promptTagDarkMode = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.promptTagDarkMode = (0, styled_components_1.css) `
6
+ --prompt-body-bg-color: var(--color-brand-subtle-bg, var(--color-warm-grey-3)); // @presenter Color
7
+ `;
8
+ //# sourceMappingURL=variables.dark.js.map
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promptTag = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.promptTag = (0, styled_components_1.css) `
6
+ /**
7
+ * @tokens Prompt
8
+ **/
9
+ --prompt-bg-color: var(--bg-color); // @presenter Color
10
+ --prompt-border-color: var(--border-color-secondary); // @presenter Color
11
+ --prompt-border-width: var(--border-width); // @presenter Border
12
+ --prompt-border-radius: var(--border-radius-xl); // @presenter BorderRadius
13
+ --prompt-margin: var(--spacing-base) 0; // @presenter Spacing
14
+ --prompt-padding-vertical: var(--spacing-sm); // @presenter Spacing
15
+ --prompt-padding-horizontal: var(--spacing-base); // @presenter Spacing
16
+ --prompt-gap: var(--spacing-sm); // @presenter Spacing
17
+ --prompt-border-highlight-color-start: var(--search-ai-gradient-start-color, var(--search-ai-gradient-start-color-legacy)); // @presenter Color
18
+ --prompt-border-highlight-color-end: var(--search-ai-gradient-end-color, var(--search-ai-gradient-end-color-legacy)); // @presenter Color
19
+ --prompt-border-highlight-size: 120px;
20
+ --prompt-border-highlight-transition: opacity 0.2s ease-out;
21
+
22
+ --prompt-header-gap: var(--spacing-xs); // @presenter Spacing
23
+ --prompt-header-actions-gap: var(--spacing-xxs); // @presenter Spacing
24
+ --prompt-header-copy-button-padding: var(--spacing-xxs); // @presenter Spacing
25
+ --prompt-icon-size: 18px;
26
+ --prompt-icon-color: var(--color-primary-base, var(--color-warm-grey-11)); // @presenter Color
27
+ --prompt-title-font-size: var(--font-size-base); // @presenter FontSize
28
+ --prompt-title-font-weight: var(--font-weight-semibold); // @presenter FontWeight
29
+ --prompt-title-line-height: var(--line-height-base); // @presenter LineHeight
30
+ --prompt-title-text-color: var(--text-color-primary); // @presenter Color
31
+
32
+ --prompt-body-bg-color: var(--color-primary-bg, var(--color-warm-grey-2)); // @presenter Color
33
+ --prompt-body-border-radius: var(--border-radius-lg); // @presenter BorderRadius
34
+ --prompt-body-padding-vertical: var(--spacing-xs); // @presenter Spacing
35
+ --prompt-body-padding-horizontal: var(--spacing-sm); // @presenter Spacing
36
+ --prompt-body-gap: var(--spacing-xxs); // @presenter Spacing
37
+ --prompt-body-font-size: var(--font-size-base); // @presenter FontSize
38
+ --prompt-body-line-height: var(--line-height-base); // @presenter LineHeight
39
+ --prompt-body-text-color: var(--text-color-primary); // @presenter Color
40
+ --prompt-body-max-lines: 5;
41
+ --prompt-body-toggle-gap: var(--spacing-xxs); // @presenter Spacing
42
+ // @tokens End
43
+ `;
44
+ //# sourceMappingURL=variables.js.map
@@ -28,3 +28,4 @@ export * from '../../markdoc/components/Icon/Icon';
28
28
  export * from '../../markdoc/components/ConnectMCP/ConnectMCP';
29
29
  export * from '../../markdoc/components/LoginButton/LoginButton';
30
30
  export * from '../../markdoc/components/MarkdownLink/MarkdownLink';
31
+ export * from '../../markdoc/components/Prompt/Prompt';
@@ -44,4 +44,5 @@ __exportStar(require("../../markdoc/components/Icon/Icon"), exports);
44
44
  __exportStar(require("../../markdoc/components/ConnectMCP/ConnectMCP"), exports);
45
45
  __exportStar(require("../../markdoc/components/LoginButton/LoginButton"), exports);
46
46
  __exportStar(require("../../markdoc/components/MarkdownLink/MarkdownLink"), exports);
47
+ __exportStar(require("../../markdoc/components/Prompt/Prompt"), exports);
47
48
  //# sourceMappingURL=default.js.map
@@ -30,6 +30,7 @@ import { icon } from '../markdoc/tags/icon';
30
30
  import { connectMcp } from '../markdoc/tags/connect-mcp';
31
31
  import { loginButton } from '../markdoc/tags/login-button';
32
32
  import { diagram } from '../markdoc/tags/diagram';
33
+ import { prompt } from '../markdoc/tags/prompt';
33
34
  export declare const tags: {
34
35
  [accordion.tagName]: import("./tags/types").MarkdocTagSchema;
35
36
  [accordionGroup.tagName]: import("./tags/types").MarkdocTagSchema;
@@ -56,4 +57,5 @@ export declare const tags: {
56
57
  [connectMcp.tagName]: import("./tags/types").MarkdocTagSchema;
57
58
  [loginButton.tagName]: import("./tags/types").MarkdocTagSchema;
58
59
  [diagram.tagName]: import("./tags/types").MarkdocTagSchema;
60
+ [prompt.tagName]: import("./tags/types").MarkdocTagSchema;
59
61
  };
@@ -72,6 +72,7 @@ const icon_1 = require("../markdoc/tags/icon");
72
72
  const connect_mcp_1 = require("../markdoc/tags/connect-mcp");
73
73
  const login_button_1 = require("../markdoc/tags/login-button");
74
74
  const diagram_1 = require("../markdoc/tags/diagram");
75
+ const prompt_1 = require("../markdoc/tags/prompt");
75
76
  exports.tags = {
76
77
  [accordion_1.accordion.tagName]: accordion_1.accordion.schema,
77
78
  [accordion_group_1.accordionGroup.tagName]: accordion_group_1.accordionGroup.schema,
@@ -98,5 +99,6 @@ exports.tags = {
98
99
  [connect_mcp_1.connectMcp.tagName]: connect_mcp_1.connectMcp.schema,
99
100
  [login_button_1.loginButton.tagName]: login_button_1.loginButton.schema,
100
101
  [diagram_1.diagram.tagName]: diagram_1.diagram.schema,
102
+ [prompt_1.prompt.tagName]: prompt_1.prompt.schema,
101
103
  };
102
104
  //# sourceMappingURL=default.js.map
@@ -2,7 +2,7 @@ import type { Node, RenderableTreeNode } from '@markdoc/markdoc';
2
2
  import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
3
3
  import type { CodeWalkthroughConditions, CodeWalkthroughFilter, TogglesMarkdocAttr, InputsMarkdocAttr } from '../../core/types';
4
4
  export declare const codeWalkthrough: MarkdocSchemaWrapper;
5
- export declare function collectStepsFromChildren(children: RenderableTreeNode[], idx?: number): RenderableTreeNode[];
5
+ export declare function collectStepsFromChildren(children: RenderableTreeNode[]): RenderableTreeNode[];
6
6
  export declare function collectTogglesFromChildren(children: Node[], toggles?: TogglesMarkdocAttr): TogglesMarkdocAttr;
7
7
  export declare function collectInputsFromChildren(children: RenderableTreeNode[], inputs?: InputsMarkdocAttr): InputsMarkdocAttr;
8
8
  export declare function validateCodeWalkthroughCondition(conditions: CodeWalkthroughConditions, filters: Record<string, CodeWalkthroughFilter>, allToggles: string[]): string[];
@@ -56,9 +56,7 @@ exports.codeWalkthrough = {
56
56
  const steps = collectStepsFromChildren(children);
57
57
  const inputs = collectInputsFromChildren(children);
58
58
  const toggles = collectTogglesFromChildren(node.children);
59
- return new markdoc_1.default.Tag('CodeWalkthrough', Object.assign(Object.assign({}, attributes), { filters: node.attributes.filters || {}, filesets: node.attributes.resolvedFilesets || [], steps: steps.map((step) => {
60
- return Object.assign({}, ((step === null || step === void 0 ? void 0 : step.attributes) || {}));
61
- }), inputs,
59
+ return new markdoc_1.default.Tag('CodeWalkthrough', Object.assign(Object.assign({}, attributes), { filters: node.attributes.filters || {}, filesets: node.attributes.resolvedFilesets || [], steps: steps.map((step) => step.attributes), inputs,
62
60
  toggles }), children);
63
61
  },
64
62
  validate(node) {
@@ -147,14 +145,14 @@ exports.codeWalkthrough = {
147
145
  render: 'CodeWalkthrough',
148
146
  },
149
147
  };
150
- function collectStepsFromChildren(children, idx = 0) {
148
+ function collectStepsFromChildren(children) {
151
149
  return children.flatMap((child) => {
152
150
  const isTag = markdoc_1.default.Tag.isTag(child);
153
151
  if (!isTag)
154
152
  return [];
155
153
  if (child.name === 'CodeStep')
156
154
  return [child];
157
- return collectStepsFromChildren(child.children, idx);
155
+ return collectStepsFromChildren(child.children);
158
156
  });
159
157
  }
160
158
  function collectTogglesFromChildren(children, toggles = {}) {
@@ -0,0 +1,2 @@
1
+ import type { MarkdocSchemaWrapper } from '../../markdoc/tags/types';
2
+ export declare const prompt: MarkdocSchemaWrapper;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.prompt = void 0;
7
+ const markdoc_1 = __importDefault(require("@markdoc/markdoc"));
8
+ const constants_1 = require("../../core/constants");
9
+ const ALLOWED_ACTIONS = Object.values(constants_1.AI_PROMPT_TARGETS);
10
+ exports.prompt = {
11
+ schema: {
12
+ render: 'Prompt',
13
+ attributes: {
14
+ title: { type: String },
15
+ icon: { type: String, resolver: 'relativeOrCdnIcon' },
16
+ iconRawContent: { type: String, render: true }, // internal
17
+ actions: { type: Array, default: [] },
18
+ hidePrompt: { type: Boolean, default: false },
19
+ singleLine: { type: Boolean, default: false },
20
+ buttonOnly: { type: Boolean, default: false },
21
+ rawContent: { type: String, render: false, resolver: 'tagRawContent' }, // internal
22
+ },
23
+ transform(node, config) {
24
+ const attributes = node.transformAttributes(config);
25
+ const actions = Array.isArray(attributes.actions)
26
+ ? [...new Set(attributes.actions.filter((action) => ALLOWED_ACTIONS.includes(action)))]
27
+ : [];
28
+ const prompt = getRawBody(node);
29
+ return new markdoc_1.default.Tag('Prompt', Object.assign(Object.assign({}, attributes), { actions, prompt }), []);
30
+ },
31
+ validate(node) {
32
+ const errors = [];
33
+ const { actions } = node.attributes;
34
+ if (Array.isArray(actions)) {
35
+ for (const action of actions) {
36
+ if (!ALLOWED_ACTIONS.includes(action)) {
37
+ errors.push({
38
+ id: 'prompt-unknown-action',
39
+ level: 'error',
40
+ message: `attribute "actions" contains unknown value "${action}"; allowed values: ${ALLOWED_ACTIONS.join(', ')}`,
41
+ });
42
+ }
43
+ }
44
+ }
45
+ return errors;
46
+ },
47
+ // The prompt is for human readers: it stays out of the .md page, llms.txt, and AI search.
48
+ renderForLlms: () => '',
49
+ },
50
+ tagName: constants_1.PROMPT_TAG,
51
+ };
52
+ function getRawBody(node) {
53
+ const rawContent = node.attributes.rawContent;
54
+ return typeof rawContent === 'string' ? rawContent : '';
55
+ }
56
+ //# sourceMappingURL=prompt.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.70.0-next.8",
3
+ "version": "0.70.0",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -42,7 +42,7 @@
42
42
  "devDependencies": {
43
43
  "@babel/core": "7.29.7",
44
44
  "@markdoc/markdoc": "0.5.2",
45
- "@redocly/realm-asyncapi-sdk": "0.16.0-next.4",
45
+ "@redocly/realm-asyncapi-sdk": "0.16.0",
46
46
  "@redocly/tooling-test-utils": "0.0.0",
47
47
  "@shikijs/types": "3.21.0",
48
48
  "@testing-library/react": "16.3.0",
@@ -52,7 +52,6 @@
52
52
  "@types/lodash.debounce": "4.0.9",
53
53
  "@types/lodash.throttle": "4.1.9",
54
54
  "@types/node": "24.1.0",
55
- "@types/nprogress": "0.2.3",
56
55
  "@types/react": "^19.2.7",
57
56
  "@types/react-dom": "^19.2.3",
58
57
  "@vitest/coverage-v8": "4.1.11",
@@ -62,10 +61,7 @@
62
61
  "resize-observer-polyfill": "1.5.1",
63
62
  "rimraf": "5.0.7",
64
63
  "styled-components": "^6.4.2",
65
- "ts-node": "10.9.2",
66
64
  "tsc-alias": "1.8.16",
67
- "tsconfig-paths": "4.2.0",
68
- "tsconfig-paths-webpack-plugin": "3.5.2",
69
65
  "typescript": "6.0.3",
70
66
  "vitest": "4.1.11",
71
67
  "vitest-when": "0.6.2",
@@ -84,7 +80,6 @@
84
80
  "jszip": "3.10.1",
85
81
  "lodash.debounce": "^4.0.8",
86
82
  "lodash.throttle": "4.1.1",
87
- "nprogress": "0.2.0",
88
83
  "openapi-sampler": "^1.7.6",
89
84
  "react-calendar": "5.1.0",
90
85
  "react-date-picker": "11.0.0"
@@ -0,0 +1,113 @@
1
+ import React, { useEffect, useRef, useState, useSyncExternalStore } from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { JSX } from 'react';
5
+
6
+ import { isLoadInProgress, subscribeToLoadProgress } from '@redocly/theme/core/utils';
7
+
8
+ export type LoadProgressBarProps = {
9
+ /** Also shows the bar while the host's own navigation is pending. */
10
+ pending?: boolean;
11
+ className?: string;
12
+ };
13
+
14
+ const START = 0.08;
15
+ const MAX_PENDING = 0.994;
16
+ const TRICKLE_MS = 100;
17
+ const SETTLE_MS = 200;
18
+ // [below, step]: large steps at first, smaller ones near the end.
19
+ const TRICKLE_STEPS = [
20
+ [0.2, 0.1],
21
+ [0.5, 0.04],
22
+ [0.8, 0.02],
23
+ [0.99, 0.005],
24
+ ] as const;
25
+
26
+ function trickle(progress: number): number {
27
+ const step = TRICKLE_STEPS.find(([below]) => progress < below)?.[1] ?? 0;
28
+ return Math.min(progress + step, MAX_PENDING);
29
+ }
30
+
31
+ /** A top-of-page bar while a page load is pending. */
32
+ export function LoadProgressBar({
33
+ pending = false,
34
+ className,
35
+ }: LoadProgressBarProps): JSX.Element | null {
36
+ const loading = useSyncExternalStore(subscribeToLoadProgress, isLoadInProgress, () => false);
37
+ const active = pending || loading;
38
+ const [progress, setProgress] = useState<number | null>(null);
39
+ const [fading, setFading] = useState(false);
40
+ const shown = useRef(false);
41
+
42
+ useEffect(() => {
43
+ if (active) {
44
+ shown.current = true;
45
+ setFading(false);
46
+ setProgress((current) => (current === null || current === 1 ? START : current));
47
+ const timer = setInterval(
48
+ () => setProgress((current) => trickle(current ?? START)),
49
+ TRICKLE_MS,
50
+ );
51
+ return () => clearInterval(timer);
52
+ }
53
+ if (!shown.current) return undefined;
54
+
55
+ setProgress(1);
56
+ const fade = setTimeout(() => setFading(true), SETTLE_MS);
57
+ const hide = setTimeout(() => {
58
+ shown.current = false;
59
+ setProgress(null);
60
+ setFading(false);
61
+ }, SETTLE_MS * 2);
62
+ return () => {
63
+ clearTimeout(fade);
64
+ clearTimeout(hide);
65
+ };
66
+ }, [active]);
67
+
68
+ if (progress === null) return null;
69
+
70
+ // The id and class names come from the replaced nprogress library: custom styles target them.
71
+ return (
72
+ <LoadProgressBarWrapper
73
+ id="nprogress"
74
+ data-component-name="LoadProgressBar/LoadProgressBar"
75
+ className={className}
76
+ aria-hidden="true"
77
+ $fading={fading}
78
+ >
79
+ <Bar className="bar" $progress={progress}>
80
+ <Peg className="peg" />
81
+ </Bar>
82
+ </LoadProgressBarWrapper>
83
+ );
84
+ }
85
+
86
+ const LoadProgressBarWrapper = styled.div<{ $fading: boolean }>`
87
+ pointer-events: none;
88
+ opacity: ${({ $fading }) => ($fading ? 0 : 1)};
89
+ transition: opacity ${SETTLE_MS}ms linear;
90
+ `;
91
+
92
+ // The offset changes on each tick: as a styled rule, each value would add a class.
93
+ const Bar = styled.div.attrs<{ $progress: number }>(({ $progress }) => ({
94
+ style: { transform: `translate3d(${($progress - 1) * 100}%, 0, 0)` },
95
+ }))`
96
+ position: fixed;
97
+ z-index: var(--z-index-popover);
98
+ top: 0;
99
+ left: 0;
100
+ width: 100%;
101
+ height: var(--load-progress-bar-height);
102
+ background: var(--load-progress-bar-color);
103
+ transition: transform ${SETTLE_MS}ms ease;
104
+ `;
105
+
106
+ const Peg = styled.div`
107
+ position: absolute;
108
+ right: 0;
109
+ width: 100px;
110
+ height: 100%;
111
+ box-shadow: var(--load-progress-bar-shadow);
112
+ transform: rotate(3deg) translate(0, -4px);
113
+ `;
@@ -11,3 +11,4 @@ export * from './feedback';
11
11
  export * from './heading';
12
12
  export * from './markdown';
13
13
  export * from './consent';
14
+ export * from './prompt';