@redocly/theme 0.69.0-next.9 → 0.70.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Buttons/DownloadButton.js +13 -3
- package/lib/components/Catalog/Catalog.d.ts +2 -2
- package/lib/components/Catalog/CatalogActionsRow.d.ts +3 -2
- package/lib/components/Catalog/CatalogCardView/CatalogCard.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntities.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntities.js +1 -0
- package/lib/components/Catalog/CatalogEntitiesEmptyState.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.js +1 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistoryButton.d.ts +3 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistoryButton.js +45 -23
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +67 -33
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityRevisionItem.d.ts +3 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityRevisionItem.js +15 -3
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityVersionItem.d.ts +3 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityVersionItem.js +48 -57
- package/lib/components/Catalog/CatalogEntity/CatalogEntityInfoBar.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityLinks.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityMetadata.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityProperties.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/ContactProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/DomainsProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/EntityTypeProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/FormatProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/GitProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/OwnersProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/OwnersProperty.js +1 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/UserEmailProperty.d.ts +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityDefaultRelations.d.ts +2 -3
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.d.ts +3 -4
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent.d.ts +3 -4
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -2
- package/lib/components/Catalog/CatalogEntityIcon.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntityTypeTag.d.ts +2 -2
- package/lib/components/Catalog/CatalogFilter/CatalogFilterContent.d.ts +1 -1
- package/lib/components/Catalog/CatalogFilter/CatalogFilterContent.js +1 -2
- package/lib/components/Catalog/CatalogHighlight.d.ts +2 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.d.ts +2 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelHeader.d.ts +1 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.d.ts +2 -1
- package/lib/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBar.d.ts +2 -2
- package/lib/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBarControls.d.ts +2 -2
- package/lib/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBarFiltersButton.d.ts +1 -1
- package/lib/components/Catalog/CatalogSelector.d.ts +3 -2
- package/lib/components/Catalog/CatalogTableView/CatalogEntityCell.d.ts +1 -1
- package/lib/components/Catalog/CatalogTableView/CatalogTableHeaderCell.d.ts +1 -1
- package/lib/components/Catalog/CatalogTableView/CatalogTableView.d.ts +2 -1
- package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.d.ts +2 -1
- package/lib/components/Catalog/CatalogTableView/CatalogTagsCell.d.ts +1 -1
- package/lib/components/Catalog/CatalogTags.d.ts +2 -2
- package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
- package/lib/components/Catalog/variables.js +24 -33
- package/lib/components/CatalogClassic/CatalogClassicInfoBlock.d.ts +1 -1
- package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +1 -2
- package/lib/components/CatalogClassic/CatalogClassicVirtualizedGroups.d.ts +1 -1
- package/lib/components/CodeBlock/CodeBlockControls.d.ts +1 -1
- package/lib/components/Dropdown/Dropdown.js +7 -1
- package/lib/components/Filter/FilterOptionLabel.d.ts +1 -1
- package/lib/components/LoadMore/LoadMore.d.ts +1 -1
- package/lib/components/MCP/McpConnectionTabs.js +22 -12
- package/lib/components/Markdown/Markdown.js +1 -3
- package/lib/components/Markdown/styles/base-table.js +8 -0
- package/lib/components/Markdown/variables.js +1 -2
- package/lib/components/PageActions/PageActions.d.ts +1 -1
- package/lib/components/Search/SearchAiDialog.d.ts +1 -1
- package/lib/components/Search/SearchAiDialog.js +3 -0
- package/lib/components/Search/SearchAiMessage.d.ts +1 -2
- package/lib/components/Search/SearchAiMessage.js +8 -10
- package/lib/components/Search/SearchAiResponse.d.ts +1 -1
- package/lib/components/Search/SearchGroups.d.ts +1 -1
- package/lib/core/constants/markdown.d.ts +2 -0
- package/lib/core/constants/markdown.js +3 -1
- package/lib/core/contexts/AccordionGroupContext.d.ts +1 -0
- package/lib/core/contexts/AccordionGroupContext.js +6 -0
- package/lib/core/contexts/PageActionsContext.d.ts +5 -0
- package/lib/core/contexts/PageActionsContext.js +10 -0
- package/lib/core/contexts/index.d.ts +2 -0
- package/lib/core/contexts/index.js +2 -0
- package/lib/core/hooks/catalog/use-catalog-entity-schema.d.ts +1 -1
- package/lib/core/hooks/catalog/use-catalog-table-header-cell-actions.d.ts +1 -1
- package/lib/core/hooks/catalog/use-graph.d.ts +3 -3
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +1 -0
- package/lib/core/hooks/use-active-heading.js +4 -0
- package/lib/core/hooks/use-active-section-id.js +6 -0
- package/lib/core/hooks/use-connect-mcp-button.js +7 -2
- package/lib/core/hooks/use-element-size.d.ts +1 -1
- package/lib/core/hooks/use-product-picker.js +1 -1
- package/lib/core/hooks/use-tabs.js +4 -2
- package/lib/core/hooks/use-telemetry-fallback.d.ts +2 -0
- package/lib/core/hooks/use-telemetry-fallback.js +2 -0
- package/lib/core/styles/global.js +1 -0
- package/lib/core/types/catalog.d.ts +2 -3
- package/lib/core/types/common.d.ts +1 -1
- package/lib/core/types/hooks.d.ts +4 -7
- package/lib/core/utils/class-names.d.ts +1 -0
- package/lib/core/utils/class-names.js +7 -0
- package/lib/core/utils/mcp.d.ts +0 -1
- package/lib/core/utils/mcp.js +0 -13
- package/lib/core/utils/menu.d.ts +2 -2
- package/lib/core/utils/urls.js +1 -3
- package/lib/ext/use-configure-replay.d.ts +1 -1
- package/lib/layouts/OIDCForbidden.js +1 -1
- package/lib/markdoc/components/Accordion/Accordion.js +6 -6
- package/lib/markdoc/components/Accordion/AccordionGroup.d.ts +2 -1
- package/lib/markdoc/components/Accordion/AccordionGroup.js +39 -3
- package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.d.ts +1 -2
- package/lib/markdoc/components/Diagram/Diagram.d.ts +1 -1
- package/lib/markdoc/components/Diagram/Diagram.js +1 -2
- package/lib/markdoc/components/Heading/Heading.js +5 -2
- package/lib/markdoc/components/Tabs/Tab.d.ts +1 -1
- package/lib/markdoc/components/Tabs/TabList.d.ts +1 -1
- package/lib/markdoc/tags/accordion-group.js +3 -0
- package/lib/markdoc/tags/code-walkthrough.d.ts +1 -1
- package/lib/markdoc/tags/markdoc-example.js +34 -22
- package/package.json +2 -2
- package/src/components/Buttons/DownloadButton.tsx +16 -8
- package/src/components/Catalog/Catalog.tsx +4 -4
- package/src/components/Catalog/CatalogActionsRow.tsx +3 -2
- package/src/components/Catalog/CatalogCardView/CatalogCard.tsx +3 -2
- package/src/components/Catalog/CatalogEntities.tsx +4 -2
- package/src/components/Catalog/CatalogEntitiesEmptyState.tsx +2 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +6 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.tsx +4 -5
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistoryButton.tsx +56 -35
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +80 -42
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityRevisionItem.tsx +18 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityVersionItem.tsx +61 -75
- package/src/components/Catalog/CatalogEntity/CatalogEntityInfoBar.tsx +2 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityLinks.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityMetadata.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityProperties.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityPropertyCard.tsx +2 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/ContactProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/DomainsProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/EntityTypeProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/FormatProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/GitProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/OwnersProperty.tsx +3 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/UserEmailProperty.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +2 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityDefaultRelations.tsx +7 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.tsx +2 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +7 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent.tsx +3 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx +3 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -2
- package/src/components/Catalog/CatalogEntityIcon.tsx +3 -2
- package/src/components/Catalog/CatalogEntityTypeTag.tsx +3 -2
- package/src/components/Catalog/CatalogFilter/CatalogFilterContent.tsx +2 -4
- package/src/components/Catalog/CatalogHighlight.tsx +2 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +2 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelHeader.tsx +2 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -1
- package/src/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBar.tsx +3 -2
- package/src/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBarControls.tsx +3 -2
- package/src/components/Catalog/CatalogMobileTopBar/CatalogMobileTopBarFiltersButton.tsx +2 -1
- package/src/components/Catalog/CatalogSelector.tsx +3 -2
- package/src/components/Catalog/CatalogTableView/CatalogEntityCell.tsx +1 -1
- package/src/components/Catalog/CatalogTableView/CatalogTableHeaderCell.tsx +1 -1
- package/src/components/Catalog/CatalogTableView/CatalogTableView.tsx +2 -1
- package/src/components/Catalog/CatalogTableView/CatalogTableViewRow.tsx +2 -1
- package/src/components/Catalog/CatalogTableView/CatalogTagsCell.tsx +1 -1
- package/src/components/Catalog/CatalogTags.tsx +4 -2
- package/src/components/Catalog/CatalogViewModeToggle.tsx +1 -1
- package/src/components/Catalog/variables.ts +24 -33
- package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +2 -5
- package/src/components/CatalogClassic/CatalogClassicVirtualizedGroups.tsx +1 -1
- package/src/components/CodeBlock/CodeBlockControls.tsx +2 -1
- package/src/components/Dropdown/Dropdown.tsx +5 -1
- package/src/components/Filter/FilterOptionLabel.tsx +1 -1
- package/src/components/LoadMore/LoadMore.tsx +2 -1
- package/src/components/MCP/McpConnectionTabs.tsx +35 -14
- package/src/components/Markdown/Markdown.tsx +1 -3
- package/src/components/Markdown/styles/base-table.ts +8 -0
- package/src/components/Markdown/variables.ts +1 -2
- package/src/components/PageActions/PageActions.tsx +2 -1
- package/src/components/Search/SearchAiDialog.tsx +4 -1
- package/src/components/Search/SearchAiMessage.tsx +3 -6
- package/src/components/Search/SearchAiResponse.tsx +2 -4
- package/src/components/Search/SearchGroups.tsx +1 -5
- package/src/core/constants/markdown.ts +4 -0
- package/src/core/contexts/AccordionGroupContext.tsx +3 -0
- package/src/core/contexts/PageActionsContext.tsx +7 -0
- package/src/core/contexts/index.ts +2 -0
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +2 -0
- package/src/core/hooks/catalog/use-catalog-entity-schema.ts +1 -1
- package/src/core/hooks/catalog/use-catalog-table-header-cell-actions.ts +1 -1
- package/src/core/hooks/catalog/use-graph.ts +4 -4
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -0
- package/src/core/hooks/menu/__mocks__/use-mobile-menu-items.ts +1 -1
- package/src/core/hooks/use-active-heading.ts +4 -0
- package/src/core/hooks/use-active-section-id.ts +8 -0
- package/src/core/hooks/use-connect-mcp-button.ts +8 -2
- package/src/core/hooks/use-element-size.ts +2 -1
- package/src/core/hooks/use-product-picker.ts +2 -2
- package/src/core/hooks/use-tabs.ts +4 -2
- package/src/core/hooks/use-telemetry-fallback.ts +2 -0
- package/src/core/styles/global.ts +1 -0
- package/src/core/types/catalog.ts +7 -3
- package/src/core/types/common.ts +1 -1
- package/src/core/types/hooks.ts +15 -13
- package/src/core/utils/class-names.ts +8 -0
- package/src/core/utils/mcp.ts +0 -17
- package/src/core/utils/menu.ts +2 -2
- package/src/core/utils/urls.ts +1 -3
- package/src/ext/use-configure-replay.ts +3 -3
- package/src/layouts/OIDCForbidden.tsx +1 -1
- package/src/markdoc/components/Accordion/Accordion.tsx +8 -2
- package/src/markdoc/components/Accordion/AccordionGroup.tsx +9 -2
- package/src/markdoc/components/CodeWalkthrough/CodePanelPreview.tsx +2 -2
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +2 -4
- package/src/markdoc/components/Diagram/Diagram.tsx +2 -5
- package/src/markdoc/components/Heading/Heading.tsx +7 -4
- package/src/markdoc/components/Tabs/Tab.tsx +1 -1
- package/src/markdoc/components/Tabs/TabList.tsx +1 -1
- package/src/markdoc/tags/accordion-group.ts +3 -0
- package/src/markdoc/tags/code-walkthrough.ts +2 -1
- package/src/markdoc/tags/markdoc-example.ts +45 -28
|
@@ -286,18 +286,22 @@ export function useActiveHeading(
|
|
|
286
286
|
return;
|
|
287
287
|
}
|
|
288
288
|
const headers = findHeaders(contentElement);
|
|
289
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-chain-state-updates -- headings and the initial active heading come from DOM queries and scroll measurement, available only after layout
|
|
289
290
|
setHeadingElements(headers);
|
|
290
291
|
|
|
291
292
|
if (headers.length > 0 && !heading) {
|
|
292
293
|
if (isTopOfPage()) {
|
|
294
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-chain-state-updates -- see above
|
|
293
295
|
setHeading(headers[0].id);
|
|
294
296
|
} else {
|
|
295
297
|
const totalHeight = scrollY + window.innerHeight;
|
|
296
298
|
if (totalHeight >= document.body.scrollHeight - 10) {
|
|
299
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-chain-state-updates -- see above
|
|
297
300
|
setHeading(headers[headers.length - 1]?.id || undefined);
|
|
298
301
|
} else {
|
|
299
302
|
const triggerOffset = getTriggerOffset();
|
|
300
303
|
const activeHeader = findActiveHeaderByVirtualPosition(headers, scrollY, triggerOffset);
|
|
304
|
+
// oxlint-disable-next-line react-you-might-not-need-an-effect/no-chain-state-updates -- see above
|
|
301
305
|
setHeading(activeHeader.id);
|
|
302
306
|
}
|
|
303
307
|
}
|
|
@@ -43,6 +43,7 @@ export function useActiveSectionId(
|
|
|
43
43
|
const section = sections[i];
|
|
44
44
|
const rect = section.getBoundingClientRect();
|
|
45
45
|
if (rect.y < heightOffset && rect.bottom > heightOffset) {
|
|
46
|
+
if (isSkippedContent(section)) continue;
|
|
46
47
|
setItemId(section.getAttribute('data-section-id') || '');
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
@@ -73,3 +74,10 @@ export function useActiveSectionId(
|
|
|
73
74
|
|
|
74
75
|
return itemId;
|
|
75
76
|
}
|
|
77
|
+
|
|
78
|
+
function isSkippedContent(element: Element): boolean {
|
|
79
|
+
return (
|
|
80
|
+
typeof element.checkVisibility === 'function' &&
|
|
81
|
+
!element.checkVisibility({ contentVisibilityAuto: true })
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -8,6 +8,7 @@ import { useMCPConfig } from './use-mcp-config';
|
|
|
8
8
|
import { ClipboardService } from '../utils/clipboard-service';
|
|
9
9
|
import { DEFAULT_MCP_OPTIONS } from '../constants/mcp';
|
|
10
10
|
import { generateClaudeCodeCommand, generateCodexCommand } from '../utils/mcp';
|
|
11
|
+
import { getBaseDataAttributes } from '../utils/telemetry/get-base-data-attributes';
|
|
11
12
|
|
|
12
13
|
export type McpButtonOptions = {
|
|
13
14
|
options?: MCPOption[];
|
|
@@ -27,8 +28,9 @@ const COPIED_RESET_TIMEOUT = 1000;
|
|
|
27
28
|
export function useConnectMCPButton({
|
|
28
29
|
options = DEFAULT_MCP_OPTIONS,
|
|
29
30
|
}: McpButtonOptions = {}): McpButtonSettings {
|
|
30
|
-
const { useTranslate } = useThemeHooks();
|
|
31
|
+
const { useTranslate, useTelemetry } = useThemeHooks();
|
|
31
32
|
const { translate } = useTranslate();
|
|
33
|
+
const telemetry = useTelemetry();
|
|
32
34
|
const { serverName, serverUrl, cursorUrl, vscodeUrl } = useMCPConfig();
|
|
33
35
|
const [copiedOption, setCopiedOption] = useState<MCPOption | null>(null);
|
|
34
36
|
|
|
@@ -40,6 +42,10 @@ export function useConnectMCPButton({
|
|
|
40
42
|
|
|
41
43
|
const handleAction = useCallback(
|
|
42
44
|
(action: MCPOption) => {
|
|
45
|
+
telemetry.sendConnectMcpClickedMessage([
|
|
46
|
+
{ ...getBaseDataAttributes('connectMcp', 'button'), option: action },
|
|
47
|
+
]);
|
|
48
|
+
|
|
43
49
|
const connection = { serverName, url: serverUrl };
|
|
44
50
|
const copyTextMap: Partial<Record<MCPOption, string>> = {
|
|
45
51
|
copy: JSON.stringify(
|
|
@@ -66,7 +72,7 @@ export function useConnectMCPButton({
|
|
|
66
72
|
|
|
67
73
|
window.open(urlMap[action], '_blank');
|
|
68
74
|
},
|
|
69
|
-
[cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied],
|
|
75
|
+
[cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied, telemetry],
|
|
70
76
|
);
|
|
71
77
|
|
|
72
78
|
const triggerButtonText = useMemo(
|
|
@@ -4,7 +4,7 @@ import { useNavigate } from 'react-router';
|
|
|
4
4
|
import { getProductClassName } from '@redocly/theme/components/Product/utils';
|
|
5
5
|
|
|
6
6
|
import { useThemeHooks } from './use-theme-hooks';
|
|
7
|
-
import { withPathPrefix, generateBeforeAfterContext } from '../utils';
|
|
7
|
+
import { withPathPrefix, generateBeforeAfterContext, getSafeClassName } from '../utils';
|
|
8
8
|
|
|
9
9
|
export function useProductPicker() {
|
|
10
10
|
const { useCurrentProduct, useProducts, useTelemetry, useLoadAndNavigate } = useThemeHooks();
|
|
@@ -36,7 +36,7 @@ export function useProductPicker() {
|
|
|
36
36
|
Array.from(root.classList)
|
|
37
37
|
.filter((c) => c.startsWith('product-'))
|
|
38
38
|
.forEach((c) => root.classList.remove(c));
|
|
39
|
-
root.classList.add(getProductClassName(freshProduct.name));
|
|
39
|
+
root.classList.add(getSafeClassName(getProductClassName(freshProduct.name)));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
loadAndNavigate({ navigate, to: withPathPrefix(freshProduct.link) });
|
|
@@ -289,14 +289,16 @@ export const useActiveTab = ({ initialTab, tabsId }: UseActiveTabProps) => {
|
|
|
289
289
|
const [activeTab, setActiveTab] = useState<string | undefined>(undefined);
|
|
290
290
|
const resolvedActiveTab = activeTab ?? initialTab;
|
|
291
291
|
const prevActiveTabRef = useRef(resolvedActiveTab);
|
|
292
|
+
const isTabResolvedFromHashRef = useRef(false);
|
|
292
293
|
|
|
293
294
|
useEffect(() => {
|
|
294
|
-
if (
|
|
295
|
+
if (isTabResolvedFromHashRef.current) {
|
|
295
296
|
return;
|
|
296
297
|
}
|
|
298
|
+
isTabResolvedFromHashRef.current = true;
|
|
297
299
|
|
|
298
300
|
setActiveTab(getInitialTab({ initialTab, hash: location.hash, tabsId }));
|
|
299
|
-
}, [
|
|
301
|
+
}, [initialTab, location.hash, tabsId]);
|
|
300
302
|
|
|
301
303
|
useEffect(() => {
|
|
302
304
|
const hasActiveTabChanged = prevActiveTabRef.current !== resolvedActiveTab;
|
|
@@ -36,6 +36,8 @@ export const useTelemetryFallback = () => ({
|
|
|
36
36
|
sendProductPickerChangedMessage: () => {},
|
|
37
37
|
sendLogoClickedMessage: () => {},
|
|
38
38
|
sendCodeSnippetReportedMessage: () => {},
|
|
39
|
+
sendConnectMcpClickedMessage: () => {},
|
|
40
|
+
sendMcpConnectionSnippetCopiedMessage: () => {},
|
|
39
41
|
sendMobileMenuClosedMessage: () => {},
|
|
40
42
|
sendMobileMenuOpenedMessage: () => {},
|
|
41
43
|
sendPageViewedMessage: () => {},
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
|
|
2
|
-
import {
|
|
1
|
+
import type { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type {
|
|
3
|
+
ENTITY_RELATION_TYPES,
|
|
4
|
+
CatalogEntityConfig,
|
|
5
|
+
EntitiesCatalogConfig,
|
|
6
|
+
LayoutVariant,
|
|
7
|
+
} from '@redocly/config';
|
|
3
8
|
|
|
4
|
-
import type { CatalogEntityConfig, EntitiesCatalogConfig, LayoutVariant } from '@redocly/config';
|
|
5
9
|
import type { CatalogFilterConfig } from '@redocly/theme/config';
|
|
6
10
|
|
|
7
11
|
export type FilterResult = {
|
package/src/core/types/common.ts
CHANGED
package/src/core/types/hooks.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ResolvedBannerConfig,
|
|
3
|
+
PageData,
|
|
4
|
+
PageProps,
|
|
5
|
+
ResolvedNavItemWithLink,
|
|
6
|
+
Version,
|
|
7
|
+
} from '@redocly/config';
|
|
2
8
|
import type { AsyncApiRealmUI } from '@redocly/realm-asyncapi-sdk';
|
|
3
|
-
import type { PageData, PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
|
|
4
9
|
import type { ShikiTransformer } from '@shikijs/types';
|
|
5
10
|
import type { Callback, TFunction as TFunc } from 'i18next';
|
|
6
11
|
import type { To, Location, NavigateFunction } from 'react-router';
|
|
@@ -14,9 +19,15 @@ import type {
|
|
|
14
19
|
UseCatalogProps,
|
|
15
20
|
CatalogApiParams,
|
|
16
21
|
CatalogApiResults,
|
|
22
|
+
BffCatalogEntity,
|
|
23
|
+
BffCatalogEntityList,
|
|
24
|
+
BffCatalogRelatedEntity,
|
|
25
|
+
BffCatalogRelatedEntityList,
|
|
26
|
+
BffCatalogEntityRevision,
|
|
27
|
+
BffCatalogEntityRevisionList,
|
|
17
28
|
} from './catalog';
|
|
18
29
|
import type { UserMenuData } from './user-menu';
|
|
19
|
-
import type { ItemState } from './sidebar';
|
|
30
|
+
import type { ItemState, DrilldownMenuItemDetails } from './sidebar';
|
|
20
31
|
import type {
|
|
21
32
|
SearchItemData,
|
|
22
33
|
SearchFacet,
|
|
@@ -29,17 +40,8 @@ import type {
|
|
|
29
40
|
import type { SubmitFeedbackParams } from './feedback';
|
|
30
41
|
import type { TFunction } from './l10n';
|
|
31
42
|
import type { BreadcrumbItem } from './breadcrumb';
|
|
32
|
-
import type { DrilldownMenuItemDetails } from './sidebar';
|
|
33
43
|
|
|
34
|
-
import {
|
|
35
|
-
BffCatalogEntity,
|
|
36
|
-
BffCatalogEntityList,
|
|
37
|
-
BffCatalogRelatedEntity,
|
|
38
|
-
BffCatalogRelatedEntityList,
|
|
39
|
-
BffCatalogEntityRevision,
|
|
40
|
-
BffCatalogEntityRevisionList,
|
|
41
|
-
} from './catalog';
|
|
42
|
-
import { AiSearchError } from '../constants/search';
|
|
44
|
+
import type { AiSearchError } from '../constants/search';
|
|
43
45
|
|
|
44
46
|
export type ThemeHooks = {
|
|
45
47
|
useAnchorPositioning: () => { isSupported: boolean };
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
const SPACE_DELIMITER = ' ';
|
|
2
2
|
|
|
3
|
+
// EasyList/AdGuard ship generic cosmetic rules that hide these exact class tokens on every
|
|
4
|
+
// site; the trailing underscore keeps the class usable without matching the filter lists.
|
|
5
|
+
const ADBLOCK_HIDDEN_CLASS_NAMES = new Set(['product-ad', 'product-ads', 'product-inlist-ad']);
|
|
6
|
+
|
|
7
|
+
export function getSafeClassName(className: string): string {
|
|
8
|
+
return ADBLOCK_HIDDEN_CLASS_NAMES.has(className) ? `${className}_` : className;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
export function concatClassNames(...args: Array<string | undefined>): string {
|
|
4
12
|
return args
|
|
5
13
|
.map((className) => (className ? className.trim() : className))
|
package/src/core/utils/mcp.ts
CHANGED
|
@@ -42,23 +42,6 @@ export function slugifyMcpServerName(name: string): string {
|
|
|
42
42
|
.replace(/^-+|-+$/g, '');
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// Claude Desktop's config file only launches stdio commands, so remote servers
|
|
46
|
-
// connect through the mcp-remote bridge.
|
|
47
|
-
export function generateClaudeDesktopConfig(config: McpConnectionParams): string {
|
|
48
|
-
return JSON.stringify(
|
|
49
|
-
{
|
|
50
|
-
mcpServers: {
|
|
51
|
-
[slugifyMcpServerName(config.serverName)]: {
|
|
52
|
-
command: 'npx',
|
|
53
|
-
args: ['-y', 'mcp-remote', config.url],
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
null,
|
|
58
|
-
2,
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
45
|
export function generateClaudeCodeCommand(config: McpConnectionParams): string {
|
|
63
46
|
return `claude mcp add --transport http ${slugifyMcpServerName(config.serverName)} ${config.url}`;
|
|
64
47
|
}
|
package/src/core/utils/menu.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ResolvedNavItem, Version } from '@redocly/config';
|
|
2
2
|
import type { Location } from 'react-router';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import type { Locale, TFunction } from '../types/l10n';
|
|
5
|
+
import type { ItemState } from '../types/sidebar';
|
|
6
6
|
import { MenuItemType } from '../constants/common';
|
|
7
7
|
import { getPathnameForLocale, withoutPathPrefix, withPathPrefix } from './urls';
|
|
8
8
|
|
package/src/core/utils/urls.ts
CHANGED
|
@@ -5,9 +5,7 @@ import { DEFAULT_LOCALE_PLACEHOLDER } from '../constants/common';
|
|
|
5
5
|
export function combineUrls(baseURL: string, ...relativeURLs: (string | undefined)[]) {
|
|
6
6
|
let res = baseURL;
|
|
7
7
|
for (let relativeURL of relativeURLs) {
|
|
8
|
-
res = relativeURL
|
|
9
|
-
? res.replace(/[\/\\]+$/, '') + '/' + relativeURL.replace(/^[\/\\]+/, '')
|
|
10
|
-
: res;
|
|
8
|
+
res = relativeURL ? res.replace(/[/\\]+$/, '') + '/' + relativeURL.replace(/^[/\\]+/, '') : res;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
return res;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback, useRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import type {
|
|
4
|
+
ConfigureRequestValues,
|
|
5
|
+
ConfigureServerRequestValues,
|
|
6
6
|
} from '@redocly/theme/ext/configure';
|
|
7
7
|
import type { UserClaims, OpenAPIServer, OpenAPIInfo } from '@redocly/theme/core/types';
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@ export function OIDCForbidden(): JSX.Element {
|
|
|
14
14
|
|
|
15
15
|
// use whatever you want here
|
|
16
16
|
const URL_REGEX =
|
|
17
|
-
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._
|
|
17
|
+
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
|
18
18
|
|
|
19
19
|
const renderText = (text: string) =>
|
|
20
20
|
text.split(' ').map((part: string) =>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
2
|
import styled, { keyframes } from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX, PropsWithChildren } from 'react';
|
|
5
5
|
|
|
6
6
|
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
|
|
7
7
|
import { ACCORDION_COMPONENT_NAME } from '@redocly/theme/core/constants';
|
|
8
|
+
import { AccordionGroupContext } from '@redocly/theme/core/contexts';
|
|
8
9
|
|
|
9
10
|
export type AccordionProps = {
|
|
10
11
|
title: string;
|
|
@@ -22,10 +23,13 @@ export function Accordion({
|
|
|
22
23
|
'data-source': dataSource,
|
|
23
24
|
'data-hash': dataHash,
|
|
24
25
|
}: PropsWithChildren<AccordionProps>): JSX.Element {
|
|
26
|
+
const groupName = useContext(AccordionGroupContext);
|
|
27
|
+
|
|
25
28
|
return (
|
|
26
29
|
<AccordionWrapper
|
|
27
30
|
className={className}
|
|
28
31
|
open={expanded}
|
|
32
|
+
name={groupName ?? undefined}
|
|
29
33
|
data-component-name={ACCORDION_COMPONENT_NAME}
|
|
30
34
|
data-source={dataSource}
|
|
31
35
|
data-hash={dataHash}
|
|
@@ -37,7 +41,9 @@ export function Accordion({
|
|
|
37
41
|
/>
|
|
38
42
|
{title}
|
|
39
43
|
</AccordionSummary>
|
|
40
|
-
<AccordionBody>
|
|
44
|
+
<AccordionBody>
|
|
45
|
+
<AccordionGroupContext.Provider value={null}>{children}</AccordionGroupContext.Provider>
|
|
46
|
+
</AccordionBody>
|
|
41
47
|
</AccordionWrapper>
|
|
42
48
|
);
|
|
43
49
|
}
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useId } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX, PropsWithChildren } from 'react';
|
|
5
5
|
|
|
6
6
|
import { ACCORDION_GROUP_COMPONENT_NAME, ACCORDION_SELECTOR } from '@redocly/theme/core/constants';
|
|
7
|
+
import { AccordionGroupContext } from '@redocly/theme/core/contexts';
|
|
7
8
|
|
|
8
9
|
export type AccordionGroupProps = {
|
|
10
|
+
singleExpanded?: boolean;
|
|
9
11
|
className?: string;
|
|
10
12
|
};
|
|
11
13
|
|
|
12
14
|
export function AccordionGroup({
|
|
15
|
+
singleExpanded = false,
|
|
13
16
|
className,
|
|
14
17
|
children,
|
|
15
18
|
}: PropsWithChildren<AccordionGroupProps>): JSX.Element {
|
|
19
|
+
const groupName = useId();
|
|
20
|
+
|
|
16
21
|
return (
|
|
17
22
|
<AccordionGroupWrapper
|
|
18
23
|
className={className}
|
|
19
24
|
data-component-name={ACCORDION_GROUP_COMPONENT_NAME}
|
|
20
25
|
>
|
|
21
|
-
{
|
|
26
|
+
<AccordionGroupContext.Provider value={singleExpanded ? groupName : null}>
|
|
27
|
+
{children}
|
|
28
|
+
</AccordionGroupContext.Provider>
|
|
22
29
|
</AccordionGroupWrapper>
|
|
23
30
|
);
|
|
24
31
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { JSX } from 'react';
|
|
4
|
+
import type { JSX, PropsWithChildren } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
7
7
|
import { ChevronUpIcon } from '@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon';
|
|
@@ -9,10 +9,8 @@ import {
|
|
|
9
9
|
} from '@redocly/theme/core/contexts';
|
|
10
10
|
import { CodePanel } from '@redocly/theme/markdoc/components/CodeWalkthrough/CodePanel';
|
|
11
11
|
import { useCodeWalkthrough } from '@redocly/theme/core/hooks';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
GetFilterState,
|
|
15
|
-
} from '@redocly/theme/markdoc/components/CodeWalkthrough/CodeFilters';
|
|
12
|
+
import type { GetFilterState } from '@redocly/theme/markdoc/components/CodeWalkthrough/CodeFilters';
|
|
13
|
+
import { CodeFilters } from '@redocly/theme/markdoc/components/CodeWalkthrough/CodeFilters';
|
|
16
14
|
|
|
17
15
|
export type CodeWalkthroughProps = PropsWithChildren<CodeWalkthroughAttr>;
|
|
18
16
|
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useState, type JSX } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { JSX } from 'react';
|
|
5
|
-
|
|
6
4
|
import { concatClassNames } from '@redocly/theme/core/utils';
|
|
7
|
-
import { useColorSwitcher } from '@redocly/theme/core/hooks';
|
|
8
|
-
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
5
|
+
import { useColorSwitcher, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
6
|
import { SvgViewer } from '@redocly/theme/components/SvgViewer/SvgViewer';
|
|
10
7
|
|
|
11
8
|
type DiagramProps = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { createElement, isValidElement } from 'react';
|
|
1
|
+
import React, { createElement, isValidElement, useContext } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import { useLocation } from 'react-router';
|
|
4
4
|
|
|
@@ -9,6 +9,7 @@ import { concatClassNames } from '@redocly/theme/core/utils';
|
|
|
9
9
|
import { LinkIcon } from '@redocly/theme/icons/LinkIcon/LinkIcon';
|
|
10
10
|
import { PageActions } from '@redocly/theme/components/PageActions/PageActions';
|
|
11
11
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
12
|
+
import { PageActionsContext } from '@redocly/theme/core/contexts';
|
|
12
13
|
import {
|
|
13
14
|
ANCHOR_CLASS,
|
|
14
15
|
HEADING_ANCHOR_CLASS,
|
|
@@ -65,8 +66,10 @@ export function Heading({
|
|
|
65
66
|
const { usePageProps } = useThemeHooks();
|
|
66
67
|
const pageProps = usePageProps();
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
// The page-type fallback is only for backward compatibility; templates set the scope.
|
|
70
|
+
const withPageActions =
|
|
71
|
+
useContext(PageActionsContext) ??
|
|
72
|
+
(pageProps?.metadata?.type === 'markdown' || pageProps?.metadata?.type === 'asciidoc');
|
|
70
73
|
const headingTextId = `${id}-heading-text`;
|
|
71
74
|
|
|
72
75
|
const linkEl = (
|
|
@@ -101,7 +104,7 @@ export function Heading({
|
|
|
101
104
|
<HeadingContentWrapper>
|
|
102
105
|
{linkEl}
|
|
103
106
|
{headingText}
|
|
104
|
-
{
|
|
107
|
+
{withPageActions && __idx === 0 ? <PageActions pageSlug={pathname} /> : null}
|
|
105
108
|
</HeadingContentWrapper>
|
|
106
109
|
</div>
|
|
107
110
|
);
|
|
@@ -3,7 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
|
|
6
|
-
import { TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
|
|
6
|
+
import type { TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
|
|
7
7
|
import { TabButtonLink, TabItem } from '@redocly/theme/markdoc/components/Tabs/TabList';
|
|
8
8
|
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
9
9
|
|
|
@@ -5,7 +5,7 @@ import type { JSX } from 'react';
|
|
|
5
5
|
import type { TabItemProps } from '@redocly/theme/markdoc/components/Tabs/TabItemFragment';
|
|
6
6
|
|
|
7
7
|
import { Tab } from '@redocly/theme/markdoc/components/Tabs/Tab';
|
|
8
|
-
import { TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
|
|
8
|
+
import type { TabsSize } from '@redocly/theme/markdoc/components/Tabs/Tabs';
|
|
9
9
|
import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
|
|
10
10
|
import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
|
|
11
11
|
import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
|
|
@@ -3,6 +3,9 @@ import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
|
|
|
3
3
|
export const accordionGroup: MarkdocSchemaWrapper = {
|
|
4
4
|
schema: {
|
|
5
5
|
render: 'AccordionGroup',
|
|
6
|
+
attributes: {
|
|
7
|
+
singleExpanded: { type: Boolean, default: false },
|
|
8
|
+
},
|
|
6
9
|
},
|
|
7
10
|
tagName: 'accordion-group',
|
|
8
11
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Node, RenderableTreeNode, ValidationError } from '@markdoc/markdoc';
|
|
2
|
+
import markdoc from '@markdoc/markdoc';
|
|
2
3
|
|
|
3
4
|
import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
|
|
4
5
|
import type {
|
|
@@ -3,27 +3,7 @@ import markdoc from '@markdoc/markdoc';
|
|
|
3
3
|
import type { Config, Node, RenderableTreeNode } from '@markdoc/markdoc';
|
|
4
4
|
import type { MarkdocSchemaWrapper } from '@redocly/theme/markdoc/tags/types';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
function parseInlineMarkdown(
|
|
8
|
-
ast: RenderableTreeNode | RenderableTreeNode[],
|
|
9
|
-
config: Config,
|
|
10
|
-
): RenderableTreeNode | RenderableTreeNode[] {
|
|
11
|
-
if (Array.isArray(ast)) {
|
|
12
|
-
return ast.flatMap((child) => parseInlineMarkdown(child, config));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (typeof ast === 'string') {
|
|
16
|
-
const parsed = markdoc.parse(ast);
|
|
17
|
-
return markdoc.transform(parsed, config);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (ast && typeof ast === 'object' && ast.$$mdtype === 'Tag') {
|
|
21
|
-
const children = parseInlineMarkdown(ast.children, config);
|
|
22
|
-
return { ...ast, children } as RenderableTreeNode;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return ast;
|
|
26
|
-
}
|
|
6
|
+
import { EXAMPLE_CONTENT_ATTRIBUTE, MARKDOC_EXAMPLE_TAG } from '@redocly/theme/core/constants';
|
|
27
7
|
|
|
28
8
|
// This custom tag prevents evaluating any children markdoc tags (no children) so we can
|
|
29
9
|
// have markdoc examples in code fences
|
|
@@ -39,33 +19,70 @@ export const markdocExample: MarkdocSchemaWrapper = {
|
|
|
39
19
|
children: ['fence'],
|
|
40
20
|
transform(node: Node, config: Config) {
|
|
41
21
|
const attributes = node.transformAttributes(config);
|
|
42
|
-
const
|
|
22
|
+
const fenceNode = node.children[0];
|
|
23
|
+
const { content } = fenceNode?.attributes || {};
|
|
43
24
|
if (!content) return null;
|
|
44
25
|
|
|
45
26
|
const language = 'markdoc';
|
|
46
27
|
|
|
47
|
-
const annotations =
|
|
28
|
+
const annotations = fenceNode.annotations;
|
|
48
29
|
let title = null;
|
|
49
30
|
if (annotations.length > 0) {
|
|
50
31
|
const fenceWithTitle = annotations.find((annotation) => annotation.name === 'title');
|
|
51
32
|
title = fenceWithTitle?.value;
|
|
52
33
|
}
|
|
53
34
|
|
|
54
|
-
const demoContent = node.children[0].transformChildren(config);
|
|
55
|
-
const parsedDemoContent = parseInlineMarkdown(demoContent, config);
|
|
56
|
-
|
|
57
35
|
return new markdoc.Tag(
|
|
58
36
|
'MarkdocExample',
|
|
59
37
|
{
|
|
60
38
|
...attributes,
|
|
61
39
|
title,
|
|
62
40
|
language,
|
|
63
|
-
demoContent:
|
|
41
|
+
demoContent: transformDemoContent(fenceNode, content, config),
|
|
64
42
|
rawContent: content,
|
|
65
43
|
},
|
|
66
44
|
[],
|
|
67
45
|
);
|
|
68
46
|
},
|
|
69
47
|
},
|
|
70
|
-
tagName:
|
|
48
|
+
tagName: MARKDOC_EXAMPLE_TAG,
|
|
71
49
|
};
|
|
50
|
+
|
|
51
|
+
// Walk through AST and look for raw markdown to parse
|
|
52
|
+
function parseRawMarkdown(
|
|
53
|
+
ast: RenderableTreeNode | RenderableTreeNode[],
|
|
54
|
+
config: Config,
|
|
55
|
+
): RenderableTreeNode | RenderableTreeNode[] {
|
|
56
|
+
if (Array.isArray(ast)) {
|
|
57
|
+
return ast.flatMap((child) => parseRawMarkdown(child, config));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (typeof ast === 'string') {
|
|
61
|
+
const parsed = markdoc.parse(ast);
|
|
62
|
+
return markdoc.transform(parsed, config);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (ast && typeof ast === 'object' && ast.$$mdtype === 'Tag') {
|
|
66
|
+
const children = parseRawMarkdown(ast.children, config);
|
|
67
|
+
return { ...ast, children } as RenderableTreeNode;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return ast;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function toRenderableArray(node: RenderableTreeNode | RenderableTreeNode[]): RenderableTreeNode[] {
|
|
74
|
+
return Array.isArray(node) ? node : [node];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function transformDemoContent(fenceNode: Node, content: string, config: Config) {
|
|
78
|
+
const parsedBody = fenceNode.attributes[EXAMPLE_CONTENT_ATTRIBUTE] as Node | undefined;
|
|
79
|
+
if (parsedBody) {
|
|
80
|
+
return toRenderableArray(markdoc.transform(parsedBody.children, config));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!fenceNode.children.length) {
|
|
84
|
+
return toRenderableArray(markdoc.transform(markdoc.parse(content).children, config));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return toRenderableArray(parseRawMarkdown(fenceNode.transformChildren(config), config));
|
|
88
|
+
}
|