@redocly/theme 0.61.1 → 0.62.0-custom.1
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/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.d.ts +1 -0
- package/lib/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.js +12 -0
- package/lib/components/Badge/Badge.d.ts +2 -1
- package/lib/components/Badge/Badge.js +24 -2
- package/lib/components/Banner/Banner.js +19 -1
- package/lib/components/Banner/variables.js +1 -0
- package/lib/components/Breadcrumbs/Breadcrumb.js +1 -1
- package/lib/components/Breadcrumbs/BreadcrumbDropdown.js +9 -6
- package/lib/components/Breadcrumbs/Breadcrumbs.js +24 -15
- package/lib/components/Buttons/AIAssistantButton.js +7 -4
- package/lib/components/Buttons/EditPageButton.js +4 -26
- package/lib/components/Catalog/CatalogEntities.js +10 -8
- package/lib/components/Catalog/CatalogEntity/CatalogEntity.js +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +3 -3
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityVersionItem.js +6 -13
- package/lib/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.js +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.js +13 -11
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +7 -5
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +9 -7
- package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.js +1 -1
- package/lib/components/Catalog/CatalogTagsWithTooltip.js +2 -2
- package/lib/components/CatalogClassic/CatalogClassicInfoBlock.js +1 -1
- package/lib/components/CodeBlock/CodeBlockControls.js +8 -6
- package/lib/components/Dropdown/Dropdown.js +1 -1
- package/lib/components/Dropdown/variables.js +1 -0
- package/lib/components/Feedback/Comment.js +17 -4
- package/lib/components/Feedback/Mood.js +6 -3
- package/lib/components/Feedback/Rating.js +6 -3
- package/lib/components/Feedback/Scale.js +6 -3
- package/lib/components/Feedback/Sentiment.js +6 -3
- package/lib/components/Filter/FilterCheckboxes.js +1 -1
- package/lib/components/JsonViewer/JsonViewer.js +2 -2
- package/lib/components/JsonViewer/{Helpers.js → helpers.js} +2 -1
- package/lib/components/LanguagePicker/LanguagePicker.js +1 -1
- package/lib/components/Markdown/Markdown.js +2 -2
- package/lib/components/Menu/MenuItem.js +41 -15
- package/lib/components/Menu/variables.js +3 -3
- package/lib/components/Navbar/NavbarItem.js +1 -1
- package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.d.ts +1 -0
- package/lib/components/OpenApiDocs/hooks/AdditionalOverviewInfo.js +12 -0
- package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.d.ts +1 -0
- package/lib/components/OpenApiDocs/hooks/AfterOpenApiDescription.js +6 -0
- package/lib/components/PageActions/PageActions.js +25 -8
- package/lib/components/Search/SearchAiDialog.d.ts +4 -2
- package/lib/components/Search/SearchAiDialog.js +23 -4
- package/lib/components/Search/SearchAiMessage.d.ts +4 -2
- package/lib/components/Search/SearchAiMessage.js +82 -23
- package/lib/components/Search/SearchDialog.js +50 -25
- package/lib/components/Select/variables.js +2 -2
- package/lib/components/SvgViewer/SvgViewer.d.ts +15 -0
- package/lib/components/SvgViewer/SvgViewer.js +312 -0
- package/lib/components/SvgViewer/variables.d.ts +1 -0
- package/lib/components/SvgViewer/variables.dark.d.ts +1 -0
- package/lib/components/SvgViewer/variables.dark.js +8 -0
- package/lib/components/SvgViewer/variables.js +17 -0
- package/lib/components/Tag/Tag.js +1 -1
- package/lib/components/Tag/variables.dark.js +6 -0
- package/lib/components/Tag/variables.js +6 -0
- package/lib/components/Tooltip/Tooltip.d.ts +2 -3
- package/lib/components/Tooltip/Tooltip.js +66 -113
- package/lib/components/Tooltip/variables.dark.js +4 -0
- package/lib/components/Tooltip/variables.js +3 -3
- package/lib/components/UserMenu/LoginButton.d.ts +8 -2
- package/lib/components/UserMenu/LoginButton.js +4 -3
- package/lib/core/constants/feedback.d.ts +2 -0
- package/lib/core/constants/feedback.js +6 -0
- package/lib/core/constants/index.d.ts +1 -0
- package/lib/core/constants/index.js +1 -0
- package/lib/core/constants/search.d.ts +5 -1
- package/lib/core/constants/search.js +24 -1
- package/lib/core/hooks/search/use-search-dialog.js +2 -2
- package/lib/core/hooks/use-color-switcher.js +3 -1
- package/lib/core/hooks/use-mcp-config.js +2 -1
- package/lib/core/hooks/use-modal-scroll-lock.js +24 -10
- package/lib/core/hooks/use-outside-click.d.ts +3 -1
- package/lib/core/hooks/use-outside-click.js +8 -4
- package/lib/core/hooks/use-page-actions.d.ts +1 -1
- package/lib/core/hooks/use-page-actions.js +50 -14
- package/lib/core/hooks/use-product-picker.js +1 -1
- package/lib/core/hooks/use-unique-svg-ids.d.ts +6 -0
- package/lib/core/hooks/use-unique-svg-ids.js +15 -0
- package/lib/core/openapi/index.d.ts +2 -0
- package/lib/core/openapi/index.js +5 -1
- package/lib/core/styles/dark.js +13 -0
- package/lib/core/styles/global.js +38 -15
- package/lib/core/types/catalog.d.ts +1 -1
- package/lib/core/types/hooks.d.ts +23 -2
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/search.d.ts +24 -0
- package/lib/core/types/search.js +9 -1
- package/lib/core/utils/content-segments.d.ts +2 -0
- package/lib/core/utils/content-segments.js +22 -0
- package/lib/core/utils/index.d.ts +1 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/core/utils/transform-revisions-to-version-history.js +18 -68
- package/lib/ext/process-scorecard.d.ts +49 -0
- package/lib/ext/process-scorecard.js +12 -0
- package/lib/icons/DirectionRightIcon/DirectionRightIcon.d.ts +5 -0
- package/lib/icons/DirectionRightIcon/DirectionRightIcon.js +24 -0
- package/lib/icons/FitToViewIcon/FitToViewIcon.d.ts +9 -0
- package/lib/icons/FitToViewIcon/FitToViewIcon.js +25 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +8 -0
- package/lib/layouts/DocumentationLayout.js +4 -25
- package/lib/layouts/DocumentationLayoutBottom.d.ts +11 -0
- package/lib/layouts/DocumentationLayoutBottom.js +28 -0
- package/lib/layouts/DocumentationLayoutTop.d.ts +13 -0
- package/lib/layouts/DocumentationLayoutTop.js +33 -0
- package/lib/layouts/Forbidden.js +22 -18
- package/lib/markdoc/components/Cards/Card.js +1 -0
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
- package/lib/markdoc/components/Heading/Heading.js +40 -2
- package/lib/markdoc/components/LoginButton/LoginButton.d.ts +9 -0
- package/lib/markdoc/components/LoginButton/LoginButton.js +48 -0
- package/lib/markdoc/components/Mermaid/Mermaid.js +70 -2
- package/lib/markdoc/components/default.d.ts +1 -0
- package/lib/markdoc/components/default.js +1 -0
- package/lib/markdoc/default.d.ts +6 -0
- package/lib/markdoc/default.js +2 -0
- package/lib/markdoc/tags/login-button.d.ts +2 -0
- package/lib/markdoc/tags/login-button.js +32 -0
- package/package.json +10 -10
- package/src/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription.tsx +10 -0
- package/src/components/Badge/Badge.tsx +18 -2
- package/src/components/Banner/Banner.tsx +23 -1
- package/src/components/Banner/variables.ts +1 -0
- package/src/components/Breadcrumbs/Breadcrumb.tsx +3 -3
- package/src/components/Breadcrumbs/BreadcrumbDropdown.tsx +11 -8
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +24 -15
- package/src/components/Buttons/AIAssistantButton.tsx +7 -4
- package/src/components/Buttons/EditPageButton.tsx +13 -34
- package/src/components/Catalog/CatalogEntities.tsx +10 -8
- package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +3 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityVersionItem.tsx +5 -21
- package/src/components/Catalog/CatalogEntity/CatalogEntityProperties/TagsProperty.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +13 -11
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +7 -5
- package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +9 -7
- package/src/components/Catalog/CatalogTableView/CatalogTableViewRow.tsx +1 -2
- package/src/components/Catalog/CatalogTagsWithTooltip.tsx +9 -5
- package/src/components/CatalogClassic/CatalogClassicInfoBlock.tsx +3 -1
- package/src/components/CodeBlock/CodeBlockControls.tsx +16 -10
- package/src/components/Dropdown/Dropdown.tsx +1 -1
- package/src/components/Dropdown/variables.ts +1 -0
- package/src/components/Feedback/Comment.tsx +22 -4
- package/src/components/Feedback/Mood.tsx +6 -2
- package/src/components/Feedback/Rating.tsx +6 -2
- package/src/components/Feedback/Scale.tsx +6 -2
- package/src/components/Feedback/Sentiment.tsx +6 -2
- package/src/components/Filter/FilterCheckboxes.tsx +1 -1
- package/src/components/JsonViewer/JsonViewer.tsx +1 -2
- package/src/components/JsonViewer/{Helpers.tsx → helpers.tsx} +1 -0
- package/src/components/LanguagePicker/LanguagePicker.tsx +1 -1
- package/src/components/Markdown/Markdown.tsx +2 -2
- package/src/components/Menu/MenuItem.tsx +61 -16
- package/src/components/Menu/variables.ts +3 -3
- package/src/components/Navbar/NavbarItem.tsx +3 -1
- package/src/components/OpenApiDocs/hooks/AdditionalOverviewInfo.tsx +10 -0
- package/src/components/OpenApiDocs/hooks/AfterOpenApiDescription.tsx +2 -0
- package/src/components/PageActions/PageActions.tsx +38 -15
- package/src/components/Search/SearchAiDialog.tsx +31 -2
- package/src/components/Search/SearchAiMessage.tsx +103 -17
- package/src/components/Search/SearchDialog.tsx +70 -37
- package/src/components/Select/variables.ts +2 -2
- package/src/components/SvgViewer/SvgViewer.tsx +405 -0
- package/src/components/SvgViewer/variables.dark.ts +5 -0
- package/src/components/SvgViewer/variables.ts +14 -0
- package/src/components/Tag/Tag.tsx +2 -1
- package/src/components/Tag/variables.dark.ts +6 -0
- package/src/components/Tag/variables.ts +6 -0
- package/src/components/Tooltip/Tooltip.tsx +77 -120
- package/src/components/Tooltip/variables.dark.ts +4 -0
- package/src/components/Tooltip/variables.ts +3 -3
- package/src/components/UserMenu/LoginButton.tsx +23 -8
- package/src/core/constants/feedback.ts +2 -0
- package/src/core/constants/index.ts +1 -0
- package/src/core/constants/search.ts +27 -1
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +10 -1
- package/src/core/hooks/search/use-search-dialog.ts +2 -2
- package/src/core/hooks/use-color-switcher.ts +3 -1
- package/src/core/hooks/use-mcp-config.ts +2 -1
- package/src/core/hooks/use-modal-scroll-lock.ts +29 -10
- package/src/core/hooks/use-outside-click.ts +16 -5
- package/src/core/hooks/use-page-actions.ts +77 -30
- package/src/core/hooks/use-product-picker.ts +1 -1
- package/src/core/hooks/use-unique-svg-ids.ts +12 -0
- package/src/core/openapi/index.ts +2 -0
- package/src/core/styles/dark.ts +14 -0
- package/src/core/styles/global.ts +38 -15
- package/src/core/types/catalog.ts +1 -1
- package/src/core/types/hooks.ts +29 -1
- package/src/core/types/l10n.ts +13 -1
- package/src/core/types/search.ts +19 -0
- package/src/core/utils/content-segments.ts +27 -0
- package/src/core/utils/index.ts +1 -0
- package/src/core/utils/transform-revisions-to-version-history.ts +19 -99
- package/src/ext/process-scorecard.ts +59 -0
- package/src/icons/DirectionRightIcon/DirectionRightIcon.tsx +35 -0
- package/src/icons/FitToViewIcon/FitToViewIcon.tsx +26 -0
- package/src/index.ts +8 -0
- package/src/layouts/DocumentationLayout.tsx +4 -30
- package/src/layouts/DocumentationLayoutBottom.tsx +42 -0
- package/src/layouts/DocumentationLayoutTop.tsx +52 -0
- package/src/layouts/Forbidden.tsx +36 -21
- package/src/markdoc/components/Cards/Card.tsx +1 -0
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
- package/src/markdoc/components/Heading/Heading.tsx +52 -4
- package/src/markdoc/components/LoginButton/LoginButton.tsx +38 -0
- package/src/markdoc/components/Mermaid/Mermaid.tsx +57 -8
- package/src/markdoc/components/default.ts +1 -0
- package/src/markdoc/default.ts +2 -0
- package/src/markdoc/tags/login-button.ts +30 -0
- package/lib/components/Tooltip/TooltipWrapper.d.ts +0 -12
- package/lib/components/Tooltip/TooltipWrapper.js +0 -34
- package/src/components/Tooltip/TooltipWrapper.tsx +0 -70
- /package/lib/components/JsonViewer/{Helpers.d.ts → helpers.d.ts} +0 -0
|
@@ -8,72 +8,6 @@ import { VERSION_NOT_SPECIFIED } from '@redocly/theme/core/constants';
|
|
|
8
8
|
|
|
9
9
|
import { toLocalizedShortDate, toLocalizedShortDateTime } from './date';
|
|
10
10
|
|
|
11
|
-
function compareVersionsDescending(versionA: string, versionB: string): number {
|
|
12
|
-
return versionB.localeCompare(versionA, undefined, { numeric: true });
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function extractGroupComparisonData(group: CatalogEntityVersionHistoryGroup): {
|
|
16
|
-
version: string;
|
|
17
|
-
isNotSpecified: boolean;
|
|
18
|
-
time: number;
|
|
19
|
-
hasCurrent: boolean;
|
|
20
|
-
} {
|
|
21
|
-
const version = group.version;
|
|
22
|
-
const isNotSpecified = version === VERSION_NOT_SPECIFIED;
|
|
23
|
-
|
|
24
|
-
// Get version dates (oldest revision date for each group - the version's creation date)
|
|
25
|
-
// This ensures versions stay in their original order even when new revisions are added
|
|
26
|
-
const date =
|
|
27
|
-
group.singleRevisionDate ||
|
|
28
|
-
(group.revisions && group.revisions.length > 0
|
|
29
|
-
? group.revisions[group.revisions.length - 1]?.revisionDate
|
|
30
|
-
: undefined) ||
|
|
31
|
-
'';
|
|
32
|
-
const time = date ? new Date(date).getTime() : 0;
|
|
33
|
-
|
|
34
|
-
const hasCurrent = group.hasCurrentRevisionFromBackend ?? false;
|
|
35
|
-
|
|
36
|
-
return { version, isNotSpecified, time, hasCurrent };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function compareVersionGroupsDescending(
|
|
40
|
-
groupA: CatalogEntityVersionHistoryGroup,
|
|
41
|
-
groupB: CatalogEntityVersionHistoryGroup,
|
|
42
|
-
): number {
|
|
43
|
-
const {
|
|
44
|
-
version: versionA,
|
|
45
|
-
isNotSpecified: isNotSpecifiedA,
|
|
46
|
-
time: timeA,
|
|
47
|
-
hasCurrent: hasCurrentA,
|
|
48
|
-
} = extractGroupComparisonData(groupA);
|
|
49
|
-
const {
|
|
50
|
-
version: versionB,
|
|
51
|
-
isNotSpecified: isNotSpecifiedB,
|
|
52
|
-
time: timeB,
|
|
53
|
-
hasCurrent: hasCurrentB,
|
|
54
|
-
} = extractGroupComparisonData(groupB);
|
|
55
|
-
|
|
56
|
-
// First, compare by version date (oldest first, so most recent versions come first)
|
|
57
|
-
const dateComparison = timeB - timeA;
|
|
58
|
-
if (dateComparison !== 0) {
|
|
59
|
-
return dateComparison;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// If dates are equal, prioritize the one with isCurrent from backend
|
|
63
|
-
if (hasCurrentA !== hasCurrentB) {
|
|
64
|
-
return hasCurrentB ? 1 : -1; // hasCurrentB comes first if true
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// If both have same isCurrent status, compare by version
|
|
68
|
-
// If both are unknown or both are real versions, compare by version
|
|
69
|
-
if (isNotSpecifiedA === isNotSpecifiedB) {
|
|
70
|
-
return compareVersionsDescending(versionA, versionB);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// If one is unknown and one is a real version, unknown comes last
|
|
74
|
-
return isNotSpecifiedA ? 1 : -1;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
11
|
export type TransformRevisionsToVersionHistoryParams = {
|
|
78
12
|
revisions: BffCatalogEntityRevision[];
|
|
79
13
|
currentRevisionDate?: string;
|
|
@@ -100,13 +34,7 @@ export function transformRevisionsToVersionHistory({
|
|
|
100
34
|
});
|
|
101
35
|
|
|
102
36
|
const versionGroups = Array.from(versionMap.entries()).map(([version, versionRevisions]) => {
|
|
103
|
-
const
|
|
104
|
-
const dateA = a.revision ? new Date(a.revision).getTime() : 0;
|
|
105
|
-
const dateB = b.revision ? new Date(b.revision).getTime() : 0;
|
|
106
|
-
return dateB - dateA;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const latestRevision = sortedRevisions[0];
|
|
37
|
+
const latestRevision = versionRevisions[0];
|
|
110
38
|
|
|
111
39
|
const versionMatches =
|
|
112
40
|
normalizedCurrentVersion === undefined || normalizedCurrentVersion === version;
|
|
@@ -114,7 +42,7 @@ export function transformRevisionsToVersionHistory({
|
|
|
114
42
|
let isCurrent: boolean;
|
|
115
43
|
if (currentRevisionDate !== undefined) {
|
|
116
44
|
// Check if revision matches AND version matches
|
|
117
|
-
const revisionMatches =
|
|
45
|
+
const revisionMatches = versionRevisions.some((rev) => rev.revision === currentRevisionDate);
|
|
118
46
|
isCurrent = revisionMatches && versionMatches;
|
|
119
47
|
} else {
|
|
120
48
|
// When no revision is specified, use isCurrent flag from the latest revision
|
|
@@ -123,29 +51,21 @@ export function transformRevisionsToVersionHistory({
|
|
|
123
51
|
}
|
|
124
52
|
|
|
125
53
|
// Check if any revision in this version group is the default version
|
|
126
|
-
const isDefaultVersion =
|
|
127
|
-
|
|
128
|
-
const revisions =
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
name: `r.${sortedRevisions.length - index}`,
|
|
142
|
-
date: toLocalizedShortDateTime(rev.revision, locale),
|
|
143
|
-
revisionDate: rev.revision,
|
|
144
|
-
isActive: isActiveRevision || isCurrentByDefault,
|
|
145
|
-
isCurrent: rev.isCurrent ?? false,
|
|
146
|
-
};
|
|
147
|
-
})
|
|
148
|
-
: undefined;
|
|
54
|
+
const isDefaultVersion = versionRevisions.some((rev) => rev.isDefaultVersion === true);
|
|
55
|
+
|
|
56
|
+
const revisions = versionRevisions.map((rev, index): CatalogEntityRevision => {
|
|
57
|
+
const revisionMatches = currentRevisionDate ? rev.revision === currentRevisionDate : false;
|
|
58
|
+
const isActiveRevision = revisionMatches && versionMatches;
|
|
59
|
+
const isCurrentByDefault =
|
|
60
|
+
!currentRevisionDate && normalizedCurrentVersion === undefined && index === 0 && isCurrent;
|
|
61
|
+
return {
|
|
62
|
+
name: `r.${versionRevisions.length - index}`,
|
|
63
|
+
date: toLocalizedShortDateTime(rev.revision, locale),
|
|
64
|
+
revisionDate: rev.revision,
|
|
65
|
+
isActive: isActiveRevision || isCurrentByDefault,
|
|
66
|
+
isCurrent: rev.isCurrent ?? false,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
149
69
|
|
|
150
70
|
return {
|
|
151
71
|
version,
|
|
@@ -155,9 +75,9 @@ export function transformRevisionsToVersionHistory({
|
|
|
155
75
|
hasCurrentRevisionFromBackend: latestRevision?.isCurrent ?? false,
|
|
156
76
|
isDefaultVersion,
|
|
157
77
|
revisions,
|
|
158
|
-
singleRevisionDate:
|
|
78
|
+
singleRevisionDate: versionRevisions.length === 1 ? versionRevisions[0]?.revision : undefined,
|
|
159
79
|
};
|
|
160
80
|
});
|
|
161
81
|
|
|
162
|
-
return versionGroups
|
|
82
|
+
return versionGroups;
|
|
163
83
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { CatalogItem } from '@redocly/theme/core/types';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
export type ScorecardApiTableRow<TScorecard = unknown> = {
|
|
7
|
+
api: CatalogItem;
|
|
8
|
+
scorecard?: TScorecard;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ScorecardApiTableColumnStatus = 'error' | 'warning' | 'success';
|
|
12
|
+
|
|
13
|
+
export type ScorecardApiTableColumnDetails<TScorecard = unknown> = {
|
|
14
|
+
hidden?: boolean;
|
|
15
|
+
tabLabel?: string;
|
|
16
|
+
description?: ReactNode | ((row: ScorecardApiTableRow<TScorecard>) => ReactNode);
|
|
17
|
+
render?: (params: { row: ScorecardApiTableRow<TScorecard>; value: unknown }) => ReactNode;
|
|
18
|
+
status?:
|
|
19
|
+
| ScorecardApiTableColumnStatus
|
|
20
|
+
| ((params: {
|
|
21
|
+
row: ScorecardApiTableRow<TScorecard>;
|
|
22
|
+
value: unknown;
|
|
23
|
+
}) => ScorecardApiTableColumnStatus);
|
|
24
|
+
statusRule?: 'problem-if-truthy' | 'problem-if-falsy';
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type ScorecardApiTableColumn<TScorecard = unknown> = {
|
|
28
|
+
id: string;
|
|
29
|
+
header: string;
|
|
30
|
+
placement?: 'beforeLevels' | 'afterLevels';
|
|
31
|
+
size?: number;
|
|
32
|
+
minSize?: number;
|
|
33
|
+
maxSize?: number;
|
|
34
|
+
sortRule?: 'string' | 'number' | 'date';
|
|
35
|
+
sortDescFirst?: boolean;
|
|
36
|
+
getValue?: (row: ScorecardApiTableRow<TScorecard>) => unknown;
|
|
37
|
+
getSortValue?: (row: ScorecardApiTableRow<TScorecard>) => unknown;
|
|
38
|
+
render?: (params: { row: ScorecardApiTableRow<TScorecard>; value: unknown }) => ReactNode;
|
|
39
|
+
details?: ScorecardApiTableColumnDetails<TScorecard>;
|
|
40
|
+
sortingFn?: (params: {
|
|
41
|
+
rowA: ScorecardApiTableRow<TScorecard>;
|
|
42
|
+
rowB: ScorecardApiTableRow<TScorecard>;
|
|
43
|
+
valueA: unknown;
|
|
44
|
+
valueB: unknown;
|
|
45
|
+
}) => number;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export function useProcessScorecard(): {
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
processScorecard: <T = any>(scorecard: T, api: CatalogItem) => T;
|
|
51
|
+
processInfo: <T>(info: T) => T;
|
|
52
|
+
getApiTableColumns: () => ScorecardApiTableColumn[];
|
|
53
|
+
} {
|
|
54
|
+
return {
|
|
55
|
+
processScorecard: useCallback((scorecard) => scorecard, []),
|
|
56
|
+
processInfo: useCallback((info) => info, []),
|
|
57
|
+
getApiTableColumns: useCallback(() => [], []),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { IconProps } from '@redocly/theme/icons/types';
|
|
5
|
+
|
|
6
|
+
import { getCssColorVariable } from '@redocly/theme/core/utils';
|
|
7
|
+
|
|
8
|
+
const Icon = (props: IconProps) => (
|
|
9
|
+
<svg
|
|
10
|
+
width="16"
|
|
11
|
+
height="16"
|
|
12
|
+
viewBox="0 0 16 16"
|
|
13
|
+
fill="none"
|
|
14
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M9.5 4L8.79295 4.70705L11.0859 7H5C4.73478 7 4.48043 7.10536 4.29289 7.29289C4.10536 7.48043 4 7.73478 4 8V14H5V8H11.0859L8.79295 10.2929L9.5 11L13 7.5L9.5 4Z"
|
|
19
|
+
fill="#1A1C21"
|
|
20
|
+
/>
|
|
21
|
+
<path d="M5 2H4V6H5V2Z" fill="#1A1C21" />
|
|
22
|
+
</svg>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const DirectionRightIcon = styled(Icon).attrs(() => ({
|
|
26
|
+
'data-component-name': 'icons/DirectionRightIcon/DirectionRightIcon',
|
|
27
|
+
}))`
|
|
28
|
+
path {
|
|
29
|
+
fill: ${({ color }) => getCssColorVariable(color)};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
height: ${({ size }) => size || '16px'};
|
|
33
|
+
width: ${({ size }) => size || '16px'};
|
|
34
|
+
vertical-align: middle;
|
|
35
|
+
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { IconProps } from '@redocly/theme/icons/types';
|
|
5
|
+
|
|
6
|
+
import { getCssColorVariable } from '@redocly/theme/core/utils';
|
|
7
|
+
|
|
8
|
+
const Icon = (props: IconProps) => (
|
|
9
|
+
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
10
|
+
<path d="M1 1H5V2.5H2.5V5H1V1Z" />
|
|
11
|
+
<path d="M15 1H11V2.5H13.5V5H15V1Z" />
|
|
12
|
+
<path d="M1 15H5V13.5H2.5V11H1V15Z" />
|
|
13
|
+
<path d="M15 15H11V13.5H13.5V11H15V15Z" />
|
|
14
|
+
</svg>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export const FitToViewIcon = styled(Icon).attrs(() => ({
|
|
18
|
+
'data-component-name': 'icons/FitToViewIcon/FitToViewIcon',
|
|
19
|
+
}))<IconProps>`
|
|
20
|
+
path {
|
|
21
|
+
fill: ${({ color }) => getCssColorVariable(color)};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
height: ${({ size }) => size || '16px'};
|
|
25
|
+
width: ${({ size }) => size || '16px'};
|
|
26
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -27,6 +27,7 @@ export * from '@redocly/theme/components/Tags/CounterTag';
|
|
|
27
27
|
export * from '@redocly/theme/components/VersionPicker/VersionPicker';
|
|
28
28
|
export * from '@redocly/theme/components/Marker/Marker';
|
|
29
29
|
export * from '@redocly/theme/components/PageActions/PageActions';
|
|
30
|
+
export * from '@redocly/theme/components/SvgViewer/SvgViewer';
|
|
30
31
|
/* Buttons */
|
|
31
32
|
export * from '@redocly/theme/components/Buttons/CopyButton';
|
|
32
33
|
export * from '@redocly/theme/components/Buttons/EditPageButton';
|
|
@@ -95,9 +96,12 @@ export * from '@redocly/theme/components/Sidebar/Sidebar';
|
|
|
95
96
|
/* OpenApiDocs */
|
|
96
97
|
export * from '@redocly/theme/components/OpenApiDocs/hooks/AfterOpenApiOperation';
|
|
97
98
|
export * from '@redocly/theme/components/OpenApiDocs/hooks/AfterOpenApiTitle';
|
|
99
|
+
export * from '@redocly/theme/components/OpenApiDocs/hooks/AfterOpenApiDescription';
|
|
98
100
|
export * from '@redocly/theme/components/OpenApiDocs/hooks/BeforeOpenApiOperation';
|
|
99
101
|
export * from '@redocly/theme/components/OpenApiDocs/hooks/OpenApiFooter';
|
|
100
102
|
export * from '@redocly/theme/components/OpenApiDocs/hooks/OpenApiHeader';
|
|
103
|
+
export * from '@redocly/theme/components/OpenApiDocs/hooks/AdditionalOverviewInfo';
|
|
104
|
+
export * from '@redocly/theme/components/AsyncApiDocs/hooks/AfterAsyncApiChannelDescription';
|
|
101
105
|
/* SidebarActions */
|
|
102
106
|
export * from '@redocly/theme/components/SidebarActions/ChangeViewButton';
|
|
103
107
|
export * from '@redocly/theme/components/SidebarActions/SidebarActions';
|
|
@@ -293,6 +297,7 @@ export * from '@redocly/theme/icons/WorkflowHierarchyIcon/WorkflowHierarchyIcon'
|
|
|
293
297
|
export * from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
294
298
|
export * from '@redocly/theme/icons/ShareIcon/ShareIcon';
|
|
295
299
|
export * from '@redocly/theme/icons/HashtagIcon/HashtagIcon';
|
|
300
|
+
export * from '@redocly/theme/icons/FitToViewIcon/FitToViewIcon';
|
|
296
301
|
/* Layouts */
|
|
297
302
|
export * from '@redocly/theme/layouts/RootLayout';
|
|
298
303
|
export * from '@redocly/theme/layouts/PageLayout';
|
|
@@ -302,6 +307,9 @@ export * from '@redocly/theme/layouts/OIDCForbidden';
|
|
|
302
307
|
export * from '@redocly/theme/layouts/ThreePanelLayout';
|
|
303
308
|
export * from '@redocly/theme/layouts/CodeWalkthroughLayout';
|
|
304
309
|
export * from '@redocly/theme/layouts/InternalServerErrorLayout';
|
|
310
|
+
export * from '@redocly/theme/layouts/DocumentationLayout';
|
|
311
|
+
export * from '@redocly/theme/layouts/DocumentationLayoutTop';
|
|
312
|
+
export * from '@redocly/theme/layouts/DocumentationLayoutBottom';
|
|
305
313
|
/* Markdoc */
|
|
306
314
|
export * as markdoc from '@redocly/theme/markdoc/default';
|
|
307
315
|
/* DatePicker */
|
|
@@ -4,12 +4,10 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
import type { ResolvedNavItemWithLink, MarkdownConfig } from '@redocly/config';
|
|
6
6
|
|
|
7
|
-
import { EditPageButton } from '@redocly/theme/components/Buttons/EditPageButton';
|
|
8
7
|
import { breakpoints } from '@redocly/theme/core/utils';
|
|
9
|
-
import { PageNavigation } from '@redocly/theme/components/PageNavigation/PageNavigation';
|
|
10
|
-
import { LastUpdated } from '@redocly/theme/components/LastUpdated/LastUpdated';
|
|
11
|
-
import { Breadcrumbs as ThemeBreadcrumbs } from '@redocly/theme/components/Breadcrumbs/Breadcrumbs';
|
|
12
8
|
import { CodeSnippetProvider } from '@redocly/theme/core/contexts/CodeSnippetContext';
|
|
9
|
+
import { DocumentationLayoutTop } from '@redocly/theme/layouts/DocumentationLayoutTop';
|
|
10
|
+
import { DocumentationLayoutBottom } from '@redocly/theme/layouts/DocumentationLayoutBottom';
|
|
13
11
|
|
|
14
12
|
type DocumentationLayoutProps = {
|
|
15
13
|
tableOfContent: React.ReactNode;
|
|
@@ -36,21 +34,13 @@ export function DocumentationLayout({
|
|
|
36
34
|
className,
|
|
37
35
|
children,
|
|
38
36
|
}: React.PropsWithChildren<DocumentationLayoutProps>): JSX.Element {
|
|
39
|
-
const { editPage: themeEditPage } = config || {};
|
|
40
|
-
const mergedConf = editPage ? { ...themeEditPage, ...editPage } : undefined;
|
|
41
|
-
|
|
42
37
|
return (
|
|
43
38
|
<CodeSnippetProvider>
|
|
44
39
|
<LayoutWrapper data-component-name="Layout/DocumentationLayout" className={className}>
|
|
45
40
|
<ContentWrapper withToc={!config?.toc?.hide}>
|
|
46
|
-
<
|
|
47
|
-
<LayoutTop>
|
|
48
|
-
{lastModified && <LastUpdated lastModified={new Date(lastModified)} />}
|
|
49
|
-
{mergedConf && <EditPageButton to={mergedConf.to} />}
|
|
50
|
-
</LayoutTop>
|
|
41
|
+
<DocumentationLayoutTop config={config} editPage={editPage} lastModified={lastModified} />
|
|
51
42
|
{children}
|
|
52
|
-
<
|
|
53
|
-
<PageNavigation nextPage={nextPage} prevPage={prevPage} />
|
|
43
|
+
<DocumentationLayoutBottom feedback={feedback} nextPage={nextPage} prevPage={prevPage} />
|
|
54
44
|
</ContentWrapper>
|
|
55
45
|
{tableOfContent}
|
|
56
46
|
</LayoutWrapper>
|
|
@@ -89,19 +79,3 @@ const ContentWrapper = styled.section<{ withToc: boolean }>`
|
|
|
89
79
|
width: ${({ withToc }) => (withToc ? `calc(90% - var(--toc-width))` : '90%')};
|
|
90
80
|
}
|
|
91
81
|
`;
|
|
92
|
-
|
|
93
|
-
const LayoutTop = styled.div`
|
|
94
|
-
display: flex;
|
|
95
|
-
justify-content: space-between;
|
|
96
|
-
flex-flow: row nowrap;
|
|
97
|
-
`;
|
|
98
|
-
|
|
99
|
-
const Breadcrumbs = styled(ThemeBreadcrumbs)`
|
|
100
|
-
margin-bottom: var(--breadcrumbs-margin-bottom);
|
|
101
|
-
`;
|
|
102
|
-
|
|
103
|
-
const LayoutBottom = styled(LayoutTop)`
|
|
104
|
-
> * {
|
|
105
|
-
margin: 25px 0;
|
|
106
|
-
}
|
|
107
|
-
`;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { JSX } from 'react';
|
|
5
|
+
import type { ResolvedNavItemWithLink } from '@redocly/config';
|
|
6
|
+
|
|
7
|
+
import { PageNavigation } from '@redocly/theme/components/PageNavigation/PageNavigation';
|
|
8
|
+
|
|
9
|
+
type DocumentationLayoutBottomProps = {
|
|
10
|
+
feedback: React.ReactNode;
|
|
11
|
+
nextPage?: ResolvedNavItemWithLink | null;
|
|
12
|
+
prevPage?: ResolvedNavItemWithLink | null;
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function DocumentationLayoutBottom({
|
|
17
|
+
feedback,
|
|
18
|
+
nextPage,
|
|
19
|
+
prevPage,
|
|
20
|
+
}: React.PropsWithChildren<DocumentationLayoutBottomProps>): JSX.Element {
|
|
21
|
+
return (
|
|
22
|
+
<Wrapper data-component-name="Layout/DocumentationLayoutBottom">
|
|
23
|
+
<LayoutBottom>{feedback}</LayoutBottom>
|
|
24
|
+
<PageNavigation nextPage={nextPage} prevPage={prevPage} />
|
|
25
|
+
</Wrapper>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const Wrapper = styled.div`
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const LayoutBottom = styled.div`
|
|
35
|
+
display: flex;
|
|
36
|
+
justify-content: space-between;
|
|
37
|
+
flex-flow: row nowrap;
|
|
38
|
+
|
|
39
|
+
> * {
|
|
40
|
+
margin: 25px 0;
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { JSX } from 'react';
|
|
5
|
+
import type { MarkdownConfig } from '@redocly/config';
|
|
6
|
+
|
|
7
|
+
import { EditPageButton } from '@redocly/theme/components/Buttons/EditPageButton';
|
|
8
|
+
import { LastUpdated } from '@redocly/theme/components/LastUpdated/LastUpdated';
|
|
9
|
+
import { Breadcrumbs as ThemeBreadcrumbs } from '@redocly/theme/components/Breadcrumbs/Breadcrumbs';
|
|
10
|
+
|
|
11
|
+
type DocumentationLayoutTopProps = {
|
|
12
|
+
config?: MarkdownConfig;
|
|
13
|
+
editPage?: {
|
|
14
|
+
to: string;
|
|
15
|
+
};
|
|
16
|
+
/** String in ISO format */
|
|
17
|
+
lastModified?: string | null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function DocumentationLayoutTop({
|
|
21
|
+
config,
|
|
22
|
+
editPage,
|
|
23
|
+
lastModified,
|
|
24
|
+
}: React.PropsWithChildren<DocumentationLayoutTopProps>): JSX.Element {
|
|
25
|
+
const { editPage: themeEditPage } = config || {};
|
|
26
|
+
const mergedConf = editPage ? { ...themeEditPage, ...editPage } : undefined;
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Wrapper data-component-name="Layout/DocumentationLayoutTop">
|
|
30
|
+
<Breadcrumbs />
|
|
31
|
+
<LayoutTop>
|
|
32
|
+
{lastModified && <LastUpdated lastModified={new Date(lastModified)} />}
|
|
33
|
+
{mergedConf && <EditPageButton to={mergedConf.to} />}
|
|
34
|
+
</LayoutTop>
|
|
35
|
+
</Wrapper>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const Wrapper = styled.div`
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const LayoutTop = styled.div`
|
|
45
|
+
display: flex;
|
|
46
|
+
justify-content: space-between;
|
|
47
|
+
flex-flow: row nowrap;
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
const Breadcrumbs = styled(ThemeBreadcrumbs)`
|
|
51
|
+
margin-bottom: var(--breadcrumbs-margin-bottom);
|
|
52
|
+
`;
|
|
@@ -5,50 +5,65 @@ import type { JSX } from 'react';
|
|
|
5
5
|
|
|
6
6
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
7
7
|
import { Button } from '@redocly/theme/components/Button/Button';
|
|
8
|
+
import { ArrowLeftIcon } from '@redocly/theme/icons/ArrowLeftIcon/ArrowLeftIcon';
|
|
8
9
|
|
|
9
10
|
export function Forbidden(): JSX.Element {
|
|
10
11
|
const { useTranslate } = useThemeHooks();
|
|
11
12
|
const { translate } = useTranslate();
|
|
12
13
|
|
|
13
14
|
return (
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
<
|
|
15
|
+
<ForbiddenWrapper data-component-name="layouts/Forbidden">
|
|
16
|
+
<StatusText>403</StatusText>
|
|
17
|
+
<Title data-translation-key="page.forbidden.title">
|
|
17
18
|
{translate('page.forbidden.title', 'Access forbidden')}
|
|
19
|
+
</Title>
|
|
20
|
+
<Description data-translation-key="page.forbidden.description">
|
|
21
|
+
{translate(
|
|
22
|
+
'page.forbidden.description',
|
|
23
|
+
"You don't have permission to access this page. If you believe this is an error, contact your administrator or return to the homepage.",
|
|
24
|
+
)}
|
|
18
25
|
</Description>
|
|
19
|
-
<
|
|
26
|
+
<Button
|
|
27
|
+
variant="primary"
|
|
28
|
+
size="large"
|
|
29
|
+
to="/"
|
|
30
|
+
data-translation-key="page.homeButton"
|
|
31
|
+
icon={<ArrowLeftIcon />}
|
|
32
|
+
>
|
|
20
33
|
{translate('page.homeButton', 'Go home')}
|
|
21
|
-
</
|
|
22
|
-
</
|
|
34
|
+
</Button>
|
|
35
|
+
</ForbiddenWrapper>
|
|
23
36
|
);
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
const
|
|
39
|
+
const ForbiddenWrapper = styled.div`
|
|
40
|
+
height: 100%;
|
|
41
|
+
max-width: var(--page-403-max-width);
|
|
27
42
|
display: flex;
|
|
28
43
|
flex-direction: column;
|
|
29
|
-
align-items: center;
|
|
30
44
|
justify-content: center;
|
|
31
|
-
margin:
|
|
45
|
+
margin: var(--page-403-margin-vertical) var(--page-403-margin-horizontal);
|
|
32
46
|
font-family: var(--page-403-font-family);
|
|
33
|
-
|
|
47
|
+
gap: var(--page-403-gap);
|
|
34
48
|
`;
|
|
35
49
|
|
|
36
|
-
const
|
|
37
|
-
color: var(--page-403-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
const StatusText = styled.div`
|
|
51
|
+
color: var(--page-403-status-text-color);
|
|
52
|
+
font-size: var(--page-403-status-font-size);
|
|
53
|
+
line-height: var(--page-403-status-line-height);
|
|
54
|
+
font-weight: var(--page-403-status-font-weight);
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const Title = styled.div`
|
|
58
|
+
color: var(--page-403-title-text-color);
|
|
59
|
+
font-size: var(--page-403-title-font-size);
|
|
60
|
+
line-height: var(--page-403-title-line-height);
|
|
61
|
+
font-weight: var(--page-403-title-font-weight);
|
|
42
62
|
`;
|
|
43
63
|
|
|
44
64
|
const Description = styled.div`
|
|
45
65
|
color: var(--page-403-description-text-color);
|
|
46
|
-
margin: var(--page-403-description-margin);
|
|
47
66
|
font-size: var(--page-403-description-font-size);
|
|
48
67
|
line-height: var(--page-403-description-line-height);
|
|
49
68
|
font-weight: var(--page-403-description-font-weight);
|
|
50
69
|
`;
|
|
51
|
-
|
|
52
|
-
const HomeButton = styled(Button)`
|
|
53
|
-
margin-top: var(--page-403-button-margin);
|
|
54
|
-
`;
|
|
@@ -1,14 +1,44 @@
|
|
|
1
|
-
import React, { createElement } from 'react';
|
|
1
|
+
import React, { createElement, isValidElement } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import { useLocation } from 'react-router-dom';
|
|
4
4
|
|
|
5
|
-
import type { JSX, PropsWithChildren } from 'react';
|
|
5
|
+
import type { JSX, PropsWithChildren, ReactElement, ReactNode } from 'react';
|
|
6
6
|
|
|
7
|
+
import { Image as MarkdocImage } from '@redocly/theme/markdoc/components/Image/Image';
|
|
7
8
|
import { concatClassNames } from '@redocly/theme/core/utils';
|
|
8
9
|
import { LinkIcon } from '@redocly/theme/icons/LinkIcon/LinkIcon';
|
|
9
10
|
import { PageActions } from '@redocly/theme/components/PageActions/PageActions';
|
|
10
11
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
11
12
|
|
|
13
|
+
function renderWithSpanWrapper(children: ReactNode): ReactNode {
|
|
14
|
+
const childrenArray = React.Children.toArray(children);
|
|
15
|
+
|
|
16
|
+
if (childrenArray.length === 0) return null;
|
|
17
|
+
|
|
18
|
+
const first = childrenArray[0];
|
|
19
|
+
const last = childrenArray[childrenArray.length - 1];
|
|
20
|
+
|
|
21
|
+
// Check if an element is an <img> or the Markdoc Image component
|
|
22
|
+
const isImage = (node: ReactNode): node is ReactElement => {
|
|
23
|
+
if (!isValidElement(node)) return false;
|
|
24
|
+
if (typeof node.type === 'string') return node.type === 'img';
|
|
25
|
+
return node.type === MarkdocImage;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const middleChildren = childrenArray.slice(
|
|
29
|
+
isImage(first) ? 1 : 0,
|
|
30
|
+
isImage(last) ? childrenArray.length - 1 : childrenArray.length,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
{isImage(first) && first}
|
|
36
|
+
{middleChildren.length > 0 && <StyledHeadingText>{middleChildren}</StyledHeadingText>}
|
|
37
|
+
{isImage(last) && last}
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
12
42
|
/**
|
|
13
43
|
* Class name for all MD tags
|
|
14
44
|
*/
|
|
@@ -57,7 +87,7 @@ export function Heading({
|
|
|
57
87
|
},
|
|
58
88
|
<HeadingContentWrapper>
|
|
59
89
|
{linkEl}
|
|
60
|
-
<span>{children}</span>
|
|
90
|
+
<span>{renderWithSpanWrapper(children)}</span>
|
|
61
91
|
{isMarkdownPage && __idx === 0 ? <PageActions pageSlug={pathname} /> : null}
|
|
62
92
|
</HeadingContentWrapper>,
|
|
63
93
|
);
|
|
@@ -66,5 +96,23 @@ export function Heading({
|
|
|
66
96
|
const HeadingContentWrapper = styled.div`
|
|
67
97
|
display: flex;
|
|
68
98
|
gap: var(--spacing-xs);
|
|
69
|
-
|
|
99
|
+
|
|
100
|
+
& > span {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: flex-start;
|
|
103
|
+
gap: var(--spacing-sm);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&:has([data-component-name='PageActions/PageActions']:hover) {
|
|
107
|
+
&& .anchor svg {
|
|
108
|
+
visibility: hidden;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
const StyledHeadingText = styled.span`
|
|
114
|
+
margin: auto 0;
|
|
115
|
+
&& > img:only-child {
|
|
116
|
+
display: inline-block;
|
|
117
|
+
}
|
|
70
118
|
`;
|