@redocly/theme 0.58.0-next.1 → 0.58.0-next.11

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 (135) hide show
  1. package/lib/components/Catalog/Catalog.d.ts +2 -2
  2. package/lib/components/Catalog/Catalog.js +6 -4
  3. package/lib/components/Catalog/CatalogCardView/CatalogCard.js +15 -14
  4. package/lib/components/Catalog/CatalogEntity/CatalogEntity.d.ts +5 -1
  5. package/lib/components/Catalog/CatalogEntity/CatalogEntity.js +4 -4
  6. package/lib/components/Catalog/CatalogEntity/CatalogEntityLinks.js +0 -1
  7. package/lib/components/Catalog/CatalogEntity/CatalogEntityMetadata.js +3 -4
  8. package/lib/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.js +0 -1
  9. package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.js +1 -1
  10. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.js +1 -1
  11. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.d.ts +5 -1
  12. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +9 -7
  13. package/lib/components/Catalog/CatalogEntityIcon.d.ts +2 -0
  14. package/lib/components/Catalog/CatalogEntityIcon.js +31 -14
  15. package/lib/components/Catalog/CatalogEntityTypeIcon.js +19 -6
  16. package/lib/components/Catalog/CatalogEntityTypeTag.js +9 -3
  17. package/lib/components/Catalog/CatalogSelector.d.ts +1 -1
  18. package/lib/components/Catalog/CatalogTableView/CatalogEntityCell.js +1 -1
  19. package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
  20. package/lib/components/Catalog/variables.js +9 -6
  21. package/lib/components/CatalogClassic/CatalogClassic.js +9 -2
  22. package/lib/components/CodeBlock/CodeBlock.d.ts +5 -12
  23. package/lib/components/CodeBlock/CodeBlockControls.d.ts +3 -3
  24. package/lib/components/CodeBlock/CodeBlockControls.js +1 -1
  25. package/lib/components/CodeBlock/CodeBlockDropdown.d.ts +2 -2
  26. package/lib/components/CodeBlock/CodeBlockDropdown.js +4 -13
  27. package/lib/components/CodeBlock/CodeBlockTabs.d.ts +2 -2
  28. package/lib/components/CodeBlock/CodeBlockTabs.js +4 -3
  29. package/lib/components/JsonViewer/JsonViewer.d.ts +1 -1
  30. package/lib/components/JsonViewer/JsonViewer.js +9 -10
  31. package/lib/components/PageActions/PageActions.d.ts +4 -1
  32. package/lib/components/PageActions/PageActions.js +2 -2
  33. package/lib/components/Search/SearchDialog.js +12 -6
  34. package/lib/components/Search/SearchFilter.js +2 -1
  35. package/lib/components/Tooltip/Tooltip.js +7 -9
  36. package/lib/components/Tooltip/TooltipWrapper.js +1 -1
  37. package/lib/core/constants/catalog.d.ts +1 -1
  38. package/lib/core/constants/catalog.js +13 -27
  39. package/lib/core/contexts/CodeSnippetContext.d.ts +14 -6
  40. package/lib/core/contexts/CodeSnippetContext.js +57 -14
  41. package/lib/core/hooks/catalog/useCatalogTableViewRow.js +1 -1
  42. package/lib/core/hooks/use-active-section-id.js +4 -0
  43. package/lib/core/hooks/use-codeblock-tabs-controls.d.ts +2 -2
  44. package/lib/core/hooks/use-control.js +17 -2
  45. package/lib/core/hooks/use-local-state.js +22 -18
  46. package/lib/core/hooks/use-page-actions.d.ts +2 -1
  47. package/lib/core/hooks/use-page-actions.js +48 -6
  48. package/lib/core/hooks/use-telemetry-fallback.d.ts +5 -0
  49. package/lib/core/hooks/use-telemetry-fallback.js +5 -0
  50. package/lib/core/openapi/index.d.ts +9 -4
  51. package/lib/core/openapi/index.js +11 -9
  52. package/lib/core/styles/global.js +19 -0
  53. package/lib/core/types/catalog.d.ts +1 -1
  54. package/lib/core/types/hooks.d.ts +2 -2
  55. package/lib/core/types/index.d.ts +1 -0
  56. package/lib/core/types/index.js +1 -0
  57. package/lib/core/types/l10n.d.ts +1 -1
  58. package/lib/core/types/open-api-info.d.ts +34 -0
  59. package/lib/core/types/open-api-info.js +3 -0
  60. package/lib/core/types/open-api-server.d.ts +1 -0
  61. package/lib/core/types/search.d.ts +2 -3
  62. package/lib/core/utils/urls.js +1 -1
  63. package/lib/ext/useConfigureReplay.d.ts +2 -1
  64. package/lib/icons/CursorIcon/CursorIcon.d.ts +9 -0
  65. package/lib/icons/CursorIcon/CursorIcon.js +22 -0
  66. package/lib/icons/HierarchyIcon/HierarchyIcon.d.ts +9 -0
  67. package/lib/icons/HierarchyIcon/HierarchyIcon.js +23 -0
  68. package/lib/icons/NoteIcon/NoteIcon.d.ts +9 -0
  69. package/lib/icons/NoteIcon/NoteIcon.js +24 -0
  70. package/lib/icons/ShareIcon/ShareIcon.d.ts +9 -0
  71. package/lib/icons/ShareIcon/ShareIcon.js +22 -0
  72. package/lib/index.d.ts +2 -0
  73. package/lib/index.js +2 -0
  74. package/lib/layouts/DocumentationLayout.js +1 -3
  75. package/lib/markdoc/components/CodeGroup/CodeGroup.js +49 -27
  76. package/lib/markdoc/components/Tabs/TabList.js +2 -0
  77. package/lib/markdoc/components/Tabs/Tabs.d.ts +2 -1
  78. package/lib/markdoc/components/Tabs/Tabs.js +3 -2
  79. package/package.json +4 -4
  80. package/src/components/Catalog/Catalog.tsx +18 -6
  81. package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +20 -19
  82. package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +15 -2
  83. package/src/components/Catalog/CatalogEntity/CatalogEntityLinks.tsx +0 -1
  84. package/src/components/Catalog/CatalogEntity/CatalogEntityMetadata.tsx +3 -4
  85. package/src/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.tsx +0 -1
  86. package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.tsx +1 -1
  87. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +1 -1
  88. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +27 -18
  89. package/src/components/Catalog/CatalogEntityIcon.tsx +53 -18
  90. package/src/components/Catalog/CatalogEntityTypeIcon.tsx +19 -8
  91. package/src/components/Catalog/CatalogEntityTypeTag.tsx +11 -3
  92. package/src/components/Catalog/CatalogSelector.tsx +1 -1
  93. package/src/components/Catalog/CatalogTableView/CatalogEntityCell.tsx +1 -1
  94. package/src/components/Catalog/CatalogViewModeToggle.tsx +1 -1
  95. package/src/components/Catalog/variables.ts +9 -6
  96. package/src/components/CatalogClassic/CatalogClassic.tsx +26 -10
  97. package/src/components/CodeBlock/CodeBlock.tsx +5 -11
  98. package/src/components/CodeBlock/CodeBlockControls.tsx +4 -7
  99. package/src/components/CodeBlock/CodeBlockDropdown.tsx +11 -20
  100. package/src/components/CodeBlock/CodeBlockTabs.tsx +8 -8
  101. package/src/components/JsonViewer/JsonViewer.tsx +16 -9
  102. package/src/components/PageActions/PageActions.tsx +6 -4
  103. package/src/components/Search/SearchDialog.tsx +14 -5
  104. package/src/components/Search/SearchFilter.tsx +2 -1
  105. package/src/components/Tooltip/Tooltip.tsx +6 -8
  106. package/src/components/Tooltip/TooltipWrapper.tsx +1 -1
  107. package/src/core/constants/catalog.ts +13 -27
  108. package/src/core/contexts/CodeSnippetContext.tsx +54 -18
  109. package/src/core/hooks/catalog/useCatalogTableViewRow.ts +1 -1
  110. package/src/core/hooks/use-active-section-id.ts +6 -0
  111. package/src/core/hooks/use-codeblock-tabs-controls.ts +2 -2
  112. package/src/core/hooks/use-control.ts +21 -3
  113. package/src/core/hooks/use-local-state.ts +28 -19
  114. package/src/core/hooks/use-page-actions.ts +63 -6
  115. package/src/core/hooks/use-telemetry-fallback.ts +5 -0
  116. package/src/core/openapi/index.ts +9 -4
  117. package/src/core/styles/global.ts +19 -0
  118. package/src/core/types/catalog.ts +1 -2
  119. package/src/core/types/hooks.ts +6 -1
  120. package/src/core/types/index.ts +1 -0
  121. package/src/core/types/l10n.ts +16 -0
  122. package/src/core/types/open-api-info.ts +34 -0
  123. package/src/core/types/open-api-server.ts +1 -0
  124. package/src/core/types/search.ts +3 -3
  125. package/src/core/utils/urls.ts +2 -1
  126. package/src/ext/useConfigureReplay.ts +2 -1
  127. package/src/icons/CursorIcon/CursorIcon.tsx +35 -0
  128. package/src/icons/HierarchyIcon/HierarchyIcon.tsx +32 -0
  129. package/src/icons/NoteIcon/NoteIcon.tsx +35 -0
  130. package/src/icons/ShareIcon/ShareIcon.tsx +23 -0
  131. package/src/index.ts +2 -0
  132. package/src/layouts/DocumentationLayout.tsx +3 -10
  133. package/src/markdoc/components/CodeGroup/CodeGroup.tsx +81 -52
  134. package/src/markdoc/components/Tabs/TabList.tsx +1 -0
  135. package/src/markdoc/components/Tabs/Tabs.tsx +10 -2
@@ -5,31 +5,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.CodeBlockDropdown = CodeBlockDropdown;
7
7
  const react_1 = __importDefault(require("react"));
8
- const styled_components_1 = __importDefault(require("styled-components"));
9
8
  const Dropdown_1 = require("../../components/Dropdown/Dropdown");
10
9
  const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
11
10
  const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
12
11
  const Button_1 = require("../../components/Button/Button");
13
- const ChevronSortIcon_1 = require("../../icons/ChevronSortIcon/ChevronSortIcon");
14
12
  const NoneIcon_1 = require("../../icons/NoneIcon/NoneIcon");
15
13
  const utils_1 = require("../../core/utils");
16
14
  function CodeBlockDropdown({ items, onChange, value }) {
17
- const activeItem = items.find((item) => item.name === value) || items[0];
15
+ const activeItem = items.find((item) => item.id === value) || items[0];
18
16
  const icon = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.lang) ? (0, utils_1.getFileIconByLanguage)(activeItem === null || activeItem === void 0 ? void 0 : activeItem.lang) : null;
19
- return (react_1.default.createElement(StyledDropdown, { alignment: "end", trigger: react_1.default.createElement(Button_1.Button, { icon: react_1.default.createElement(ChevronSortIcon_1.ChevronSortIcon, null), iconPosition: "right", variant: "text", size: "small" },
17
+ return (react_1.default.createElement(Dropdown_1.Dropdown, { withArrow: true, alignment: "end", trigger: react_1.default.createElement(Button_1.Button, { iconPosition: "right", variant: "ghost", size: "small" },
20
18
  icon,
21
19
  activeItem.name) },
22
20
  react_1.default.createElement(DropdownMenu_1.DropdownMenu, null, items.map((item) => {
23
21
  const icon = (0, utils_1.getFileIconByLanguage)(item.lang || '');
24
- return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: item.lang, onAction: () => onChange(item.name), active: item.name === activeItem.name, prefix: item.lang ? icon : react_1.default.createElement(NoneIcon_1.NoneIcon, { size: "var(--icon-size)" }) }, item.name));
22
+ const isActive = item.id === value;
23
+ return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: item.id, onAction: () => onChange(item.id), active: isActive, prefix: item.lang ? icon : react_1.default.createElement(NoneIcon_1.NoneIcon, { size: "var(--icon-size)" }) }, item.name));
25
24
  }))));
26
25
  }
27
- const StyledDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
28
- margin-left: auto;
29
- --icon-size: 18px;
30
- --button-color: var(--text-color-secondary);
31
- button.button-size-small {
32
- --button-icon-size: 18px;
33
- }
34
- `;
35
26
  //# sourceMappingURL=CodeBlockDropdown.js.map
@@ -1,6 +1,6 @@
1
1
  import type { JSX } from 'react';
2
- import type { CodeBlockTabItems } from '../../components/CodeBlock/CodeBlock';
2
+ import type { CodeBlockItems } from '../../components/CodeBlock/CodeBlock';
3
3
  export type CodeBlockTabsProps = {
4
- tabs: CodeBlockTabItems;
4
+ tabs: CodeBlockItems;
5
5
  };
6
6
  export declare function CodeBlockTabs({ tabs }: CodeBlockTabsProps): JSX.Element;
@@ -40,15 +40,16 @@ function CodeBlockTabs({ tabs }) {
40
40
  tabRefs,
41
41
  });
42
42
  (0, react_1.useEffect)(() => {
43
- const activeTab = tabRefs.current.find((tab) => (tab === null || tab === void 0 ? void 0 : tab.dataset.name) === tabs.value);
43
+ const activeTab = tabRefs.current.find((tab) => (tab === null || tab === void 0 ? void 0 : tab.dataset.id) === tabs.value);
44
44
  if (activeTab) {
45
45
  activeTab.scrollIntoView({ block: 'nearest', inline: 'center' });
46
46
  }
47
47
  }, [tabs.value]);
48
48
  return (react_1.default.createElement(CodeBlockTabsWrapper, { ref: containerRef, "data-component-name": "CodeBlock/CodeBlockTabs" },
49
49
  react_1.default.createElement(ShadowWrapper, null,
50
- react_1.default.createElement(Tabs, null, tabs.items.map(({ name, lang }, i) => {
50
+ react_1.default.createElement(Tabs, null, tabs.items.map((item, i) => {
51
51
  var _a;
52
+ const { name, lang, id } = item;
52
53
  const ext = (_a = name.match(/\.([^.]+)$/)) === null || _a === void 0 ? void 0 : _a[1];
53
54
  const fileIcon = lang
54
55
  ? (0, get_file_icon_1.getFileIconByLanguage)(lang)
@@ -57,7 +58,7 @@ function CodeBlockTabs({ tabs }) {
57
58
  : null;
58
59
  return (react_1.default.createElement(Tab, { ref: (el) => {
59
60
  tabRefs.current[i] = el;
60
- }, "data-name": name, active: name === tabs.value, key: name + i, onClick: () => tabs.onChange(name) },
61
+ }, "data-name": name, active: id === tabs.value, key: id, onClick: () => tabs.onChange(id) },
61
62
  fileIcon,
62
63
  name));
63
64
  }))),
@@ -3,11 +3,11 @@ import type { CodeBlockControlsProps } from '../../components/CodeBlock/CodeBloc
3
3
  export type PanelType = 'request' | 'responses' | 'request-samples' | 'response-samples';
4
4
  export type JsonProps = {
5
5
  title?: CodeBlockControlsProps['title'];
6
+ controls?: CodeBlockControlsProps['controls'];
6
7
  data: any;
7
8
  className?: string;
8
9
  expandLevel: number;
9
10
  startLineNumber?: number;
10
- hideHeader?: boolean;
11
11
  onCopyClick?: () => void;
12
12
  onPanelToggle?: (isExpanded: boolean, panelType?: PanelType) => void;
13
13
  };
@@ -31,7 +31,7 @@ const react_1 = __importStar(require("react"));
31
31
  const styled_components_1 = __importDefault(require("styled-components"));
32
32
  const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
33
33
  const helpers_1 = require("./helpers");
34
- function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelToggle, title, hideHeader, }) {
34
+ function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelToggle, title, controls = {}, }) {
35
35
  const showFoldingButtons = data && Object.values(data).some((value) => typeof value === 'object' && value !== null);
36
36
  const [expandAllSignal, setExpandAllSignal] = react_1.default.useState(undefined);
37
37
  const expandAll = () => {
@@ -49,18 +49,17 @@ function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelT
49
49
  });
50
50
  };
51
51
  const source = JSON.stringify(data, null, 2);
52
+ const hasHeader = title || controls;
52
53
  return (react_1.default.createElement(exports.JsonViewerWrap, { "data-testid": "json-viewer", "data-component-name": "JsonViewer/JsonViewer", className: className },
53
- react_1.default.createElement(CodeBlock_1.CodeBlock, { header: hideHeader
54
- ? undefined
55
- : {
54
+ react_1.default.createElement(CodeBlock_1.CodeBlock, { header: hasHeader
55
+ ? {
56
56
  title,
57
57
  className: 'code-block-header',
58
- controls: {
59
- copy: { data, onClick: onCopyClick, handleOutside: true },
60
- expand: showFoldingButtons ? { onClick: expandAll } : undefined,
61
- collapse: showFoldingButtons ? { onClick: collapseAll } : undefined,
62
- },
63
- }, source: source },
58
+ controls: controls && Object.assign(Object.assign({}, controls), { copy: Object.assign(Object.assign({}, controls.copy), { data, onClick: onCopyClick, handleOutside: true }), expand: showFoldingButtons
59
+ ? Object.assign(Object.assign({}, controls.expand), { onClick: expandAll }) : undefined, collapse: showFoldingButtons
60
+ ? Object.assign(Object.assign({}, controls.collapse), { onClick: collapseAll }) : undefined }),
61
+ }
62
+ : undefined, source: source },
64
63
  react_1.default.createElement(FoldingWrap, null,
65
64
  react_1.default.createElement(helpers_1.JsonValue, { value: data, level: 0, standalone: true, expandAllSignal: expandAllSignal, defaultExpandLevel: Math.max(1, expandLevel) })))));
66
65
  }
@@ -1,6 +1,9 @@
1
1
  import type { JSX } from 'react';
2
+ import { PageActionType } from '../../core/hooks';
2
3
  type PageActionProps = {
3
- pageSlug: string;
4
+ pageSlug?: string;
5
+ mcpUrl?: string;
6
+ actions?: PageActionType[];
4
7
  };
5
8
  export declare function PageActions(props: PageActionProps): JSX.Element | null;
6
9
  export {};
@@ -49,8 +49,8 @@ const CheckmarkFilledIcon_1 = require("../../icons/CheckmarkFilledIcon/Checkmark
49
49
  const hooks_1 = require("../../core/hooks");
50
50
  const ACTION_DONE_DISPLAY_DURATION = 1000;
51
51
  function PageActions(props) {
52
- const { pageSlug } = props;
53
- const actions = (0, hooks_1.usePageActions)(pageSlug || '/');
52
+ const { pageSlug, mcpUrl } = props;
53
+ const actions = (0, hooks_1.usePageActions)(pageSlug || '/', mcpUrl, props.actions);
54
54
  const [actionState, setActionState] = (0, react_1.useState)('idle');
55
55
  if (!actions.length) {
56
56
  return null;
@@ -190,8 +190,9 @@ function SearchDialog({ onClose, className }) {
190
190
  }
191
191
  }
192
192
  }, ref: aiQueryRef, tabIndex: 0, role: "option", "aria-selected": "true" },
193
- react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { color: "var(--search-ai-icon-color)", size: "36px", background: "var(--search-ai-icon-bg-color)", margin: "0 var(--spacing-md) 0 0", borderRadius: "var(--border-radius-lg)" }),
194
- react_1.default.createElement(Typography_1.Typography, { fontWeight: "var(--font-weight-semibold)" }, query),
193
+ react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { style: { flexShrink: 0 }, color: "var(--search-ai-icon-color)", size: "36px", background: "var(--search-ai-icon-bg-color)", margin: "0 var(--spacing-md) 0 0", borderRadius: "var(--border-radius-lg)" }),
194
+ react_1.default.createElement(QueryWrapper, null,
195
+ react_1.default.createElement(Typography_1.Typography, { fontWeight: "var(--font-weight-semibold)" }, query)),
195
196
  react_1.default.createElement(Typography_1.Typography, null,
196
197
  "- ",
197
198
  translate('search.ai.label', 'Ask AI assistant')),
@@ -268,10 +269,10 @@ const SearchDialogWrapper = styled_components_1.default.div `
268
269
  border-radius: 0;
269
270
 
270
271
  @media screen and (max-width: ${utils_1.breakpoints.small}) {
271
- min-height: -webkit-fill-available !important;
272
- min-height: 100dvh !important;
273
- height: auto !important;
274
- width: 100vw !important;
272
+ min-height: -webkit-fill-available;
273
+ min-height: 100dvh;
274
+ height: 100dvh;
275
+ width: 100vw;
275
276
  }
276
277
 
277
278
  @media screen and (min-width: ${utils_1.breakpoints.small}) {
@@ -318,6 +319,8 @@ const SearchDialogBodyMainView = styled_components_1.default.div `
318
319
  `;
319
320
  const SearchDialogBodyFilterView = styled_components_1.default.div `
320
321
  overflow: scroll;
322
+ max-width: var(--search-filter-width);
323
+ width: 100%;
321
324
  `;
322
325
  const SearchDialogFooter = styled_components_1.default.footer `
323
326
  display: flex;
@@ -439,4 +442,7 @@ const SearchWithAI = styled_components_1.default.div `
439
442
  margin-right: var(--spacing-xs);
440
443
  }
441
444
  `;
445
+ const QueryWrapper = styled_components_1.default.div `
446
+ word-break: break-word;
447
+ `;
442
448
  //# sourceMappingURL=SearchDialog.js.map
@@ -43,7 +43,8 @@ function SearchFilter({ className, facets, filter, query, quickFilterFields, onF
43
43
  React.createElement(SearchFilterFields, null, facets.map((facet, index) => (React.createElement(SearchFilterField_1.SearchFilterField, { key: `${facet.field}-${index}`, facet: facet, filter: filter, query: query, quickFilterFields: quickFilterFields, onFilterChange: onFilterChange, onFacetReset: onFacetReset }))))));
44
44
  }
45
45
  const SearchFilterWrapper = styled_components_1.default.div `
46
- width: var(--search-filter-width);
46
+ width: 100%;
47
+ max-width: var(--search-filter-width);
47
48
  display: flex;
48
49
  flex-direction: column;
49
50
  padding: var(--search-filter-padding);
@@ -91,15 +91,13 @@ function TooltipComponent({ children, isOpen, tip, withArrow = true, placement =
91
91
  }
92
92
  }, [isOpened, placement, updateTooltipPosition]);
93
93
  (0, react_1.useEffect)(() => {
94
- if (isControlled && !disabled) {
95
- if (isOpen) {
96
- handleOpen();
97
- }
98
- else {
99
- handleClose();
100
- }
94
+ if (isOpen && !disabled) {
95
+ handleOpen();
96
+ }
97
+ else {
98
+ handleClose();
101
99
  }
102
- }, [isOpen, isControlled, handleOpen, handleClose, disabled]);
100
+ }, [isOpen, handleOpen, handleClose, disabled]);
103
101
  const controllers = !isControlled &&
104
102
  !disabled && {
105
103
  onMouseEnter: handleOpen,
@@ -228,7 +226,7 @@ const TooltipBody = styled_components_1.default.span `
228
226
  display: inline-block;
229
227
 
230
228
  padding: var(--tooltip-padding);
231
- max-width: var(--tooltip-max-width);
229
+ max-width: ${({ width }) => width || 'var(--tooltip-max-width)'};
232
230
  white-space: normal;
233
231
  word-break: normal;
234
232
  overflow-wrap: break-word;
@@ -9,7 +9,7 @@ const react_1 = __importDefault(require("react"));
9
9
  const hooks_1 = require("../../core/hooks");
10
10
  const Tooltip_1 = require("../../components/Tooltip/Tooltip");
11
11
  function TooltipWrapper({ children, tip, placement = 'top', width = 'max-content', className = '', showOnHover = true, disabled = false, }) {
12
- const tooltip = (0, hooks_1.useControl)();
12
+ const tooltip = (0, hooks_1.useControl)(false);
13
13
  const handleMouseEnter = () => {
14
14
  if (showOnHover && !disabled) {
15
15
  tooltip.handleOpen();
@@ -1,6 +1,6 @@
1
1
  import type { EntityRelationType } from '../types/catalog';
2
2
  export declare const CATALOG_TAG_MAX_LENGTH = 15;
3
- export declare const ENTITY_RELATION_TYPES: readonly ["partOf", "hasParts", "creates", "createdBy", "owns", "ownedBy", "implements", "implementedBy", "dependsOn", "dependencyOf", "uses", "usedBy", "produces", "consumes", "linksTo", "supersedes", "supersededBy", "compatibleWith", "extends", "extendedBy", "relatesTo", "hasMember", "memberOf", "triggers", "triggeredBy"];
3
+ export declare const PREDEFINED_ENTITY_TYPES: string[];
4
4
  export declare const reverseRelationMap: Record<EntityRelationType, EntityRelationType>;
5
5
  export declare const relationTypeMap: Record<EntityRelationType, string>;
6
6
  export declare enum GraphHandleType {
@@ -1,33 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GraphCustomEdgeType = exports.GraphCustomNodeType = exports.GraphHandleType = exports.relationTypeMap = exports.reverseRelationMap = exports.ENTITY_RELATION_TYPES = exports.CATALOG_TAG_MAX_LENGTH = void 0;
3
+ exports.GraphCustomEdgeType = exports.GraphCustomNodeType = exports.GraphHandleType = exports.relationTypeMap = exports.reverseRelationMap = exports.PREDEFINED_ENTITY_TYPES = exports.CATALOG_TAG_MAX_LENGTH = void 0;
4
4
  exports.CATALOG_TAG_MAX_LENGTH = 15;
5
- exports.ENTITY_RELATION_TYPES = [
6
- 'partOf',
7
- 'hasParts',
8
- 'creates',
9
- 'createdBy',
10
- 'owns',
11
- 'ownedBy',
12
- 'implements',
13
- 'implementedBy',
14
- 'dependsOn',
15
- 'dependencyOf',
16
- 'uses',
17
- 'usedBy',
18
- 'produces',
19
- 'consumes',
20
- 'linksTo',
21
- 'supersedes',
22
- 'supersededBy',
23
- 'compatibleWith',
24
- 'extends',
25
- 'extendedBy',
26
- 'relatesTo',
27
- 'hasMember',
28
- 'memberOf',
29
- 'triggers',
30
- 'triggeredBy',
5
+ exports.PREDEFINED_ENTITY_TYPES = [
6
+ 'service',
7
+ 'domain',
8
+ 'team',
9
+ 'user',
10
+ 'api-description',
11
+ 'data-schema',
12
+ 'api-operation',
31
13
  ];
32
14
  exports.reverseRelationMap = {
33
15
  partOf: 'hasParts',
@@ -55,6 +37,8 @@ exports.reverseRelationMap = {
55
37
  memberOf: 'hasMember',
56
38
  triggers: 'triggeredBy',
57
39
  triggeredBy: 'triggers',
40
+ returns: 'returnedBy',
41
+ returnedBy: 'returns',
58
42
  };
59
43
  exports.relationTypeMap = {
60
44
  partOf: 'Part of',
@@ -82,6 +66,8 @@ exports.relationTypeMap = {
82
66
  memberOf: 'Member of',
83
67
  triggers: 'Triggers',
84
68
  triggeredBy: 'Triggered by',
69
+ returns: 'Returns',
70
+ returnedBy: 'Returned by',
85
71
  };
86
72
  var GraphHandleType;
87
73
  (function (GraphHandleType) {
@@ -1,7 +1,15 @@
1
- export type CodeSnippetContextType = {
2
- activeSnippetName: string;
3
- setActiveSnippetName: (name: string) => void;
4
- };
1
+ import React from 'react';
5
2
  export declare const CODE_GROUP_SNIPPET_NAME_KEY = "redocly:codeGroupSnippetName";
6
- export declare const CodeSnippetContext: import("react").Context<CodeSnippetContextType | null>;
7
- export declare function useActiveCodeSnippetName(mode: 'tabs' | 'dropdown'): [string, (name: string) => void];
3
+ type CodeSnippetContextType = {
4
+ activeSnippets: Record<string, string>;
5
+ setActiveSnippet: (groupId: string, snippetId: string) => void;
6
+ };
7
+ export declare const CodeSnippetContext: React.Context<CodeSnippetContextType | null>;
8
+ export declare function CodeSnippetProvider({ children }: {
9
+ children: React.ReactNode;
10
+ }): React.JSX.Element;
11
+ export declare const useCodeSnippetContext: () => CodeSnippetContextType;
12
+ export declare const useActiveCodeSnippetId: (groupId?: string, availableSnippets?: {
13
+ id: string;
14
+ }[]) => [string, (id: string) => void];
15
+ export {};
@@ -1,23 +1,66 @@
1
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CodeSnippetContext = exports.CODE_GROUP_SNIPPET_NAME_KEY = void 0;
4
- exports.useActiveCodeSnippetName = useActiveCodeSnippetName;
5
- const react_1 = require("react");
26
+ exports.useActiveCodeSnippetId = exports.useCodeSnippetContext = exports.CodeSnippetContext = exports.CODE_GROUP_SNIPPET_NAME_KEY = void 0;
27
+ exports.CodeSnippetProvider = CodeSnippetProvider;
28
+ const react_1 = __importStar(require("react"));
29
+ const use_local_state_1 = require("../hooks/use-local-state");
6
30
  exports.CODE_GROUP_SNIPPET_NAME_KEY = 'redocly:codeGroupSnippetName';
7
31
  exports.CodeSnippetContext = (0, react_1.createContext)(null);
8
- function useActiveCodeSnippetName(mode) {
32
+ function CodeSnippetProvider({ children }) {
33
+ const [activeSnippets, setActiveSnippets] = (0, use_local_state_1.useLocalState)(exports.CODE_GROUP_SNIPPET_NAME_KEY, {});
34
+ const setActiveSnippet = (0, react_1.useCallback)((groupId, snippetId) => {
35
+ setActiveSnippets(Object.assign(Object.assign({}, activeSnippets), { [groupId]: snippetId }));
36
+ }, [activeSnippets, setActiveSnippets]);
37
+ const contextValue = { activeSnippets, setActiveSnippet };
38
+ return react_1.default.createElement(exports.CodeSnippetContext.Provider, { value: contextValue }, children);
39
+ }
40
+ const useCodeSnippetContext = () => {
9
41
  const context = (0, react_1.useContext)(exports.CodeSnippetContext);
10
42
  if (!context) {
11
43
  throw new Error('useCodeSnippetContext must be used within a CodeSnippetContext');
12
44
  }
13
- const [activeSnippetName, setActiveSnippetName] = (0, react_1.useState)(mode === 'tabs' ? '' : context.activeSnippetName);
14
- if (mode === 'tabs') {
15
- // use non-synced state for tabs mode
16
- return [activeSnippetName, setActiveSnippetName];
17
- }
18
- else {
19
- // use global synced state for dropdown mode
20
- return [context.activeSnippetName, context.setActiveSnippetName];
21
- }
22
- }
45
+ return context;
46
+ };
47
+ exports.useCodeSnippetContext = useCodeSnippetContext;
48
+ const useActiveCodeSnippetId = (groupId, availableSnippets) => {
49
+ const { activeSnippets, setActiveSnippet } = (0, exports.useCodeSnippetContext)();
50
+ const storedSnippetId = groupId ? activeSnippets[groupId] || '' : '';
51
+ const activeId = (0, react_1.useMemo)(() => {
52
+ var _a;
53
+ if (!(availableSnippets === null || availableSnippets === void 0 ? void 0 : availableSnippets.length))
54
+ return storedSnippetId;
55
+ const found = storedSnippetId && availableSnippets.find((s) => s.id === storedSnippetId);
56
+ return found ? storedSnippetId : ((_a = availableSnippets[0]) === null || _a === void 0 ? void 0 : _a.id) || '';
57
+ }, [storedSnippetId, availableSnippets]);
58
+ const setActiveSnippetId = (0, react_1.useCallback)((id) => {
59
+ if (groupId) {
60
+ setActiveSnippet(groupId, id);
61
+ }
62
+ }, [groupId, setActiveSnippet]);
63
+ return [activeId, setActiveSnippetId];
64
+ };
65
+ exports.useActiveCodeSnippetId = useActiveCodeSnippetId;
23
66
  //# sourceMappingURL=CodeSnippetContext.js.map
@@ -10,7 +10,7 @@ function useCatalogTableViewRow({ entityKey, entityType, catalogConfig, entities
10
10
  }
11
11
  return Object.values((_a = entitiesCatalogConfig.catalogs) !== null && _a !== void 0 ? _a : {}).find((catalog) => {
12
12
  var _a;
13
- return (_a = catalog.includes) === null || _a === void 0 ? void 0 : _a.some((include) => include.type === entityType);
13
+ return (_a = catalog === null || catalog === void 0 ? void 0 : catalog.includes) === null || _a === void 0 ? void 0 : _a.some((include) => include.type === entityType);
14
14
  });
15
15
  };
16
16
  const getEntityDetailsLink = () => {
@@ -17,6 +17,10 @@ function useActiveSectionId(location, hasOverviewPage = false, withNavbar = true
17
17
  setItemId('');
18
18
  return;
19
19
  }
20
+ if (window.scrollY <= 0) {
21
+ setItemId(sections[0].getAttribute('data-section-id') || '');
22
+ return;
23
+ }
20
24
  for (let i = 0; i < sections.length; i++) {
21
25
  const section = sections[i];
22
26
  const rect = section.getBoundingClientRect();
@@ -1,6 +1,6 @@
1
- import type { CodeBlockTabItems } from '../../components/CodeBlock/CodeBlock';
1
+ import type { CodeBlockItems } from '../../components/CodeBlock/CodeBlock';
2
2
  type CodeBlockTabsProps = {
3
- tabs: CodeBlockTabItems;
3
+ tabs: CodeBlockItems;
4
4
  containerRef: React.RefObject<HTMLDivElement | null>;
5
5
  tabRefs: React.RefObject<HTMLButtonElement[]>;
6
6
  };
@@ -2,10 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useControl = void 0;
4
4
  const react_1 = require("react");
5
+ const DEFAULT_CONTROL_OPEN_DELAY = 300;
5
6
  const useControl = (initialVal = false) => {
6
7
  const [isOpened, setIsOpened] = (0, react_1.useState)(initialVal);
7
- const handleOpen = (0, react_1.useCallback)(() => setIsOpened(true), []);
8
- const handleClose = (0, react_1.useCallback)(() => setIsOpened(false), []);
8
+ const timeoutRef = (0, react_1.useRef)(null);
9
+ const clearOpenTimer = (0, react_1.useCallback)(() => {
10
+ if (timeoutRef.current) {
11
+ clearTimeout(timeoutRef.current);
12
+ }
13
+ }, []);
14
+ const handleOpen = (0, react_1.useCallback)(() => {
15
+ clearOpenTimer();
16
+ timeoutRef.current = setTimeout(() => {
17
+ setIsOpened(true);
18
+ }, DEFAULT_CONTROL_OPEN_DELAY);
19
+ }, [clearOpenTimer]);
20
+ const handleClose = (0, react_1.useCallback)(() => {
21
+ clearOpenTimer();
22
+ setIsOpened(false);
23
+ }, [clearOpenTimer]);
9
24
  return {
10
25
  isOpened,
11
26
  handleOpen,
@@ -2,31 +2,35 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useLocalState = useLocalState;
4
4
  const react_1 = require("react");
5
- function getInitialValue(key, initialValue) {
6
- if (typeof window === 'undefined') {
7
- return initialValue;
8
- }
5
+ const js_utils_1 = require("../utils/js-utils");
6
+ function getStoredValue(key, fallback) {
7
+ if (!(0, js_utils_1.isBrowser)())
8
+ return fallback;
9
9
  try {
10
10
  const savedValue = localStorage.getItem(key);
11
- if (savedValue) {
12
- return JSON.parse(savedValue);
13
- }
11
+ return savedValue ? JSON.parse(savedValue) : fallback;
14
12
  }
15
- catch (error) {
16
- console.error(`Error reading from localStorage for key "${key}":`, error);
13
+ catch (_a) {
14
+ return fallback;
17
15
  }
18
- return initialValue;
19
16
  }
20
17
  function useLocalState(key, initialValue) {
21
- const [value, setValue] = (0, react_1.useState)(() => getInitialValue(key, initialValue));
18
+ const [value, setValue] = (0, react_1.useState)(initialValue);
19
+ // Load stored value from localStorage after component mounts
20
+ // This ensures SSR compatibility: server and client both start with initialValue,
21
+ // then client loads the actual stored value without hydration mismatch
22
22
  (0, react_1.useEffect)(() => {
23
- try {
24
- localStorage.setItem(key, JSON.stringify(value));
25
- }
26
- catch (error) {
27
- console.error(`Error writing to localStorage for key "${key}":`, error);
23
+ if (!(0, js_utils_1.isBrowser)())
24
+ return;
25
+ setValue(getStoredValue(key, initialValue));
26
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27
+ }, [key]);
28
+ const handleSetValue = (0, react_1.useCallback)((newValue) => {
29
+ setValue(newValue);
30
+ if ((0, js_utils_1.isBrowser)()) {
31
+ localStorage.setItem(key, JSON.stringify(newValue));
28
32
  }
29
- }, [key, value]);
30
- return [value, setValue];
33
+ }, [key]);
34
+ return [value, handleSetValue];
31
35
  }
32
36
  //# sourceMappingURL=use-local-state.js.map
@@ -1,2 +1,3 @@
1
1
  import type { PageAction } from '../types';
2
- export declare function usePageActions(pageSlug: string): PageAction[];
2
+ export type PageActionType = 'copy' | 'view' | 'chatgpt' | 'claude' | 'mcp-cursor';
3
+ export declare function usePageActions(pageSlug: string, mcpUrl?: string, actions?: PageActionType[]): PageAction[];
@@ -19,9 +19,11 @@ const use_theme_hooks_1 = require("./use-theme-hooks");
19
19
  const use_theme_config_1 = require("./use-theme-config");
20
20
  const clipboard_service_1 = require("../utils/clipboard-service");
21
21
  const dom_1 = require("../utils/dom");
22
+ const CursorIcon_1 = require("../../icons/CursorIcon/CursorIcon");
22
23
  const DEFAULT_ENABLED_ACTIONS = ['copy', 'view', 'chatgpt', 'claude'];
23
- function usePageActions(pageSlug) {
24
- var _a;
24
+ const CURSOR_URL = 'cursor://anysphere.cursor-deeplink/mcp/install?name=$NAME&config=$BASE64_ENCODED_CONFIG';
25
+ function usePageActions(pageSlug, mcpUrl, actions) {
26
+ var _a, _b, _c;
25
27
  const { useTranslate, usePageData, usePageProps, usePageSharedData } = (0, use_theme_hooks_1.useThemeHooks)();
26
28
  const { translate } = useTranslate();
27
29
  const themeConfig = (0, use_theme_config_1.useThemeConfig)();
@@ -29,7 +31,7 @@ function usePageActions(pageSlug) {
29
31
  const openApiSharedData = usePageSharedData('openAPIDocsStore');
30
32
  const shouldHideAllActions = shouldHidePageActions(pageProps, themeConfig, (_a = openApiSharedData === null || openApiSharedData === void 0 ? void 0 : openApiSharedData.options) === null || _a === void 0 ? void 0 : _a.excludeFromSearch);
31
33
  const { isPublic } = usePageData() || {};
32
- const actions = (0, react_1.useMemo)(() => {
34
+ const result = (0, react_1.useMemo)(() => {
33
35
  var _a, _b;
34
36
  if (shouldHideAllActions) {
35
37
  return [];
@@ -43,9 +45,41 @@ function usePageActions(pageSlug) {
43
45
  url.searchParams.set('q', externalAiPrompt);
44
46
  return url.toString();
45
47
  }
46
- return (((_b = (_a = themeConfig.navigation) === null || _a === void 0 ? void 0 : _a.actions) === null || _b === void 0 ? void 0 : _b.items) || DEFAULT_ENABLED_ACTIONS)
48
+ return (((_b = (_a = themeConfig.navigation) === null || _a === void 0 ? void 0 : _a.actions) === null || _b === void 0 ? void 0 : _b.items) || actions || DEFAULT_ENABLED_ACTIONS)
47
49
  .map((action) => {
50
+ function generateMCPConfig(isCursor) {
51
+ const jsonConfig = {
52
+ 'mcp-server': {
53
+ url: mcpUrl,
54
+ description: 'MCP Server',
55
+ },
56
+ };
57
+ if (isCursor) {
58
+ const url = CURSOR_URL.replace('$NAME', 'mcp-server').replace('$BASE64_ENCODED_CONFIG', btoa(JSON.stringify(jsonConfig['mcp-server'])));
59
+ return url;
60
+ }
61
+ return JSON.stringify(jsonConfig, null, 2);
62
+ }
48
63
  switch (action) {
64
+ case 'mcp-cursor':
65
+ if (!mcpUrl) {
66
+ return null;
67
+ }
68
+ return {
69
+ buttonText: translate('page.actions.cursorMcpButtonText', 'Connect to Cursor'),
70
+ title: translate('page.actions.cursorMcpTitle', 'Connect to Cursor'),
71
+ description: translate('page.actions.cursorMcpDescription', 'Install MCP server on Cursor'),
72
+ iconComponent: CursorIcon_1.CursorIcon,
73
+ onClick: () => {
74
+ try {
75
+ const url = generateMCPConfig(true);
76
+ window.open(url, '_blank');
77
+ }
78
+ catch (error) {
79
+ console.error(error);
80
+ }
81
+ },
82
+ };
49
83
  case 'copy':
50
84
  return {
51
85
  buttonText: translate('page.actions.copyButtonText', 'Copy'),
@@ -99,8 +133,16 @@ function usePageActions(pageSlug) {
99
133
  }
100
134
  })
101
135
  .filter((action) => action !== null);
102
- }, [themeConfig, translate, pageSlug, isPublic, shouldHideAllActions]);
103
- return actions;
136
+ }, [
137
+ shouldHideAllActions,
138
+ pageSlug,
139
+ (_c = (_b = themeConfig.navigation) === null || _b === void 0 ? void 0 : _b.actions) === null || _c === void 0 ? void 0 : _c.items,
140
+ actions,
141
+ mcpUrl,
142
+ translate,
143
+ isPublic,
144
+ ]);
145
+ return result;
104
146
  }
105
147
  function shouldHidePageActions(pageProps, themeConfig, openapiExcludeFromSearch) {
106
148
  var _a, _b, _c, _d, _e, _f;