@redocly/theme 0.68.0-next.0 → 0.68.0-next.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/Catalog/CatalogEntities.js +2 -11
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.js +3 -16
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +3 -9
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +1 -7
- package/lib/components/Feedback/Feedback.js +4 -1
- package/lib/core/hooks/use-active-heading.js +5 -2
- package/lib/core/hooks/use-telemetry-fallback.d.ts +1 -1
- package/lib/core/hooks/use-telemetry-fallback.js +1 -1
- package/lib/core/styles/dark.js +11 -0
- package/lib/core/styles/global.js +36 -34
- package/lib/markdoc/components/NumberedList/NumberedItem.d.ts +25 -0
- package/lib/markdoc/components/NumberedList/NumberedItem.js +217 -0
- package/lib/markdoc/components/NumberedList/NumberedList.d.ts +5 -0
- package/lib/markdoc/components/NumberedList/NumberedList.js +28 -0
- package/lib/markdoc/components/NumberedList/variables.d.ts +1 -0
- package/lib/markdoc/components/NumberedList/variables.js +42 -0
- package/lib/markdoc/components/default.d.ts +2 -0
- package/lib/markdoc/components/default.js +2 -0
- package/lib/markdoc/default.js +4 -0
- package/lib/markdoc/tags/numbered-item.d.ts +2 -0
- package/lib/markdoc/tags/numbered-item.js +35 -0
- package/lib/markdoc/tags/numbered-list.d.ts +2 -0
- package/lib/markdoc/tags/numbered-list.js +28 -0
- package/package.json +1 -1
- package/src/components/Catalog/CatalogEntities.tsx +7 -11
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +8 -9
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +6 -8
- package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +2 -4
- package/src/components/Feedback/Feedback.tsx +11 -1
- package/src/core/hooks/use-active-heading.ts +7 -2
- package/src/core/hooks/use-telemetry-fallback.ts +1 -1
- package/src/core/styles/dark.ts +12 -0
- package/src/core/styles/global.ts +2 -0
- package/src/markdoc/components/NumberedList/NumberedItem.tsx +274 -0
- package/src/markdoc/components/NumberedList/NumberedList.tsx +37 -0
- package/src/markdoc/components/NumberedList/variables.ts +39 -0
- package/src/markdoc/components/default.ts +2 -0
- package/src/markdoc/default.ts +4 -0
- package/src/markdoc/tags/numbered-item.ts +46 -0
- package/src/markdoc/tags/numbered-list.ts +34 -0
|
@@ -8,6 +8,8 @@ export * from '../../markdoc/components/Tabs/TabItemFragment';
|
|
|
8
8
|
export * from '../../markdoc/components/Tabs/Tab';
|
|
9
9
|
export * from '../../markdoc/components/Tabs/TabList';
|
|
10
10
|
export * from '../../markdoc/components/Tabs/Tabs';
|
|
11
|
+
export * from '../../markdoc/components/NumberedList/NumberedItem';
|
|
12
|
+
export * from '../../markdoc/components/NumberedList/NumberedList';
|
|
11
13
|
export * from '../../markdoc/components/CodeBlock/CodeBlock';
|
|
12
14
|
export * from '../../markdoc/components/Cards/Cards';
|
|
13
15
|
export * from '../../markdoc/components/Cards/Card';
|
|
@@ -24,6 +24,8 @@ __exportStar(require("../../markdoc/components/Tabs/TabItemFragment"), exports);
|
|
|
24
24
|
__exportStar(require("../../markdoc/components/Tabs/Tab"), exports);
|
|
25
25
|
__exportStar(require("../../markdoc/components/Tabs/TabList"), exports);
|
|
26
26
|
__exportStar(require("../../markdoc/components/Tabs/Tabs"), exports);
|
|
27
|
+
__exportStar(require("../../markdoc/components/NumberedList/NumberedItem"), exports);
|
|
28
|
+
__exportStar(require("../../markdoc/components/NumberedList/NumberedList"), exports);
|
|
27
29
|
__exportStar(require("../../markdoc/components/CodeBlock/CodeBlock"), exports);
|
|
28
30
|
__exportStar(require("../../markdoc/components/Cards/Cards"), exports);
|
|
29
31
|
__exportStar(require("../../markdoc/components/Cards/Card"), exports);
|
package/lib/markdoc/default.js
CHANGED
|
@@ -53,6 +53,8 @@ const markdoc_example_1 = require("../markdoc/tags/markdoc-example");
|
|
|
53
53
|
const partial_1 = require("../markdoc/tags/partial");
|
|
54
54
|
const tab_1 = require("../markdoc/tags/tab");
|
|
55
55
|
const tabs_1 = require("../markdoc/tags/tabs");
|
|
56
|
+
const numbered_item_1 = require("../markdoc/tags/numbered-item");
|
|
57
|
+
const numbered_list_1 = require("../markdoc/tags/numbered-list");
|
|
56
58
|
const debug_1 = require("../markdoc/tags/debug");
|
|
57
59
|
const code_snippet_1 = require("../markdoc/tags/code-snippet");
|
|
58
60
|
const inline_svg_1 = require("../markdoc/tags/inline-svg");
|
|
@@ -76,6 +78,8 @@ exports.tags = {
|
|
|
76
78
|
[partial_1.partial.tagName]: partial_1.partial.schema,
|
|
77
79
|
[tab_1.tab.tagName]: tab_1.tab.schema,
|
|
78
80
|
[tabs_1.tabs.tagName]: tabs_1.tabs.schema,
|
|
81
|
+
[numbered_item_1.numberedItem.tagName]: numbered_item_1.numberedItem.schema,
|
|
82
|
+
[numbered_list_1.numberedList.tagName]: numbered_list_1.numberedList.schema,
|
|
79
83
|
[code_snippet_1.codeSnippet.tagName]: code_snippet_1.codeSnippet.schema,
|
|
80
84
|
[inline_svg_1.inlineSvg.tagName]: inline_svg_1.inlineSvg.schema,
|
|
81
85
|
[cards_1.cards.tagName]: cards_1.cards.schema,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.numberedItem = void 0;
|
|
7
|
+
const markdoc_1 = __importDefault(require("@markdoc/markdoc"));
|
|
8
|
+
const utils_1 = require("../../core/utils");
|
|
9
|
+
const HEADING_TAG_NAME = /^(Heading|h[1-6])$/;
|
|
10
|
+
exports.numberedItem = {
|
|
11
|
+
schema: {
|
|
12
|
+
transform(node, config) {
|
|
13
|
+
const attributes = node.transformAttributes(config);
|
|
14
|
+
const children = node.transformChildren(config);
|
|
15
|
+
const [first, ...body] = children;
|
|
16
|
+
if ((0, utils_1.isTag)(first) && HEADING_TAG_NAME.test(String(first.name))) {
|
|
17
|
+
const headlineLevel = typeof first.attributes.level === 'number'
|
|
18
|
+
? first.attributes.level
|
|
19
|
+
: Number(String(first.name).slice(1)) || undefined;
|
|
20
|
+
return new markdoc_1.default.Tag('NumberedItem', Object.assign(Object.assign({}, attributes), { headline: first.children, anchorId: first.attributes.id, headlineLevel }), body);
|
|
21
|
+
}
|
|
22
|
+
return new markdoc_1.default.Tag('NumberedItem', attributes, children);
|
|
23
|
+
},
|
|
24
|
+
attributes: {
|
|
25
|
+
icon: { type: String, resolver: 'relativeOrCdnIcon' },
|
|
26
|
+
iconRawContent: {
|
|
27
|
+
// internal use only
|
|
28
|
+
type: String,
|
|
29
|
+
render: true,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
tagName: 'numbered-item',
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=numbered-item.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.numberedList = void 0;
|
|
7
|
+
const markdoc_1 = __importDefault(require("@markdoc/markdoc"));
|
|
8
|
+
const utils_1 = require("../../core/utils");
|
|
9
|
+
exports.numberedList = {
|
|
10
|
+
schema: {
|
|
11
|
+
transform(node, config) {
|
|
12
|
+
const attributes = node.transformAttributes(config);
|
|
13
|
+
const items = node
|
|
14
|
+
.transformChildren(config)
|
|
15
|
+
.filter((child) => (0, utils_1.isTag)(child) && child.name === 'NumberedItem');
|
|
16
|
+
items.forEach((item, index) => {
|
|
17
|
+
item.attributes = Object.assign(Object.assign({}, item.attributes), { type: attributes.type, size: attributes.size, index: index + 1, isLast: index === items.length - 1 });
|
|
18
|
+
});
|
|
19
|
+
return new markdoc_1.default.Tag('NumberedList', attributes, items);
|
|
20
|
+
},
|
|
21
|
+
attributes: {
|
|
22
|
+
type: { type: String, matches: ['icon', 'number', 'dot'], default: 'number' },
|
|
23
|
+
size: { type: String, matches: ['small', 'medium'], default: 'medium' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
tagName: 'numbered-list',
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=numbered-list.js.map
|
package/package.json
CHANGED
|
@@ -3,11 +3,8 @@ import React, { JSX, useEffect } from 'react';
|
|
|
3
3
|
import type { CatalogEntityConfig } from '@redocly/config';
|
|
4
4
|
|
|
5
5
|
import { BffCatalogEntity, BffCatalogEntityList } from '@redocly/theme/core/types';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
useCatalogEntities,
|
|
9
|
-
useCatalogEntityDetails,
|
|
10
|
-
} from '@redocly/theme/core/hooks';
|
|
6
|
+
import { useThemeHooks, useCatalogEntities } from '@redocly/theme/core/hooks';
|
|
7
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
11
8
|
import { ArrowDownIcon } from '@redocly/theme/icons/ArrowDownIcon/ArrowDownIcon';
|
|
12
9
|
import { CatalogCardView } from '@redocly/theme/components/Catalog/CatalogCardView/CatalogCardView';
|
|
13
10
|
import { CatalogTableView } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
|
|
@@ -45,9 +42,6 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
|
|
|
45
42
|
isColumnSorted,
|
|
46
43
|
} = props;
|
|
47
44
|
|
|
48
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
49
|
-
catalogConfig,
|
|
50
|
-
});
|
|
51
45
|
const { useTelemetry, useFetchCatalogEntities } = useThemeHooks();
|
|
52
46
|
const telemetry = useTelemetry();
|
|
53
47
|
const { initialFilter } = useCatalogEntities({
|
|
@@ -76,10 +70,12 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
|
|
|
76
70
|
if (searchQuery) {
|
|
77
71
|
telemetry.sendCatalogEntitiesListSearchResultClickedMessage([
|
|
78
72
|
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
...getBaseDataAttributes(
|
|
74
|
+
'catalogEntitiesListSearchResultId',
|
|
75
|
+
'catalogEntitiesListSearchResult',
|
|
76
|
+
),
|
|
82
77
|
query: searchQuery,
|
|
78
|
+
entityId: entity.id,
|
|
83
79
|
entityKey: entity.key,
|
|
84
80
|
entityType: entity.type,
|
|
85
81
|
},
|
package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx
CHANGED
|
@@ -8,7 +8,8 @@ import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/c
|
|
|
8
8
|
import { CatalogColumn } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
|
|
9
9
|
import { CatalogActionsRow } from '@redocly/theme/components/Catalog/CatalogActionsRow';
|
|
10
10
|
import { CatalogEntityRelationsTableContent } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent';
|
|
11
|
-
import {
|
|
11
|
+
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
12
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
12
13
|
import { reverseRelationMap } from '@redocly/theme/core/constants';
|
|
13
14
|
|
|
14
15
|
export type CatalogEntityRelationsTableProps = {
|
|
@@ -51,22 +52,20 @@ export function CatalogEntityRelationsTable({
|
|
|
51
52
|
}: CatalogEntityRelationsTableProps): JSX.Element {
|
|
52
53
|
const { useTelemetry } = useThemeHooks();
|
|
53
54
|
const telemetry = useTelemetry();
|
|
54
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
55
|
-
catalogConfig,
|
|
56
|
-
entitiesCatalogConfig,
|
|
57
|
-
});
|
|
58
55
|
|
|
59
56
|
const onRowClick = (relatedEntity: BffCatalogRelatedEntity) => {
|
|
60
57
|
if (searchQuery) {
|
|
61
|
-
telemetry.
|
|
58
|
+
telemetry.sendCatalogEntitiesRelatedEntitiesListSearchResultClickedMessage([
|
|
62
59
|
{
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
...getBaseDataAttributes(
|
|
61
|
+
'catalogEntitiesRelatedEntitiesListSearchResultId',
|
|
62
|
+
'catalogEntitiesRelatedEntitiesListSearchResult',
|
|
63
|
+
),
|
|
66
64
|
query: searchQuery,
|
|
67
65
|
entityKey: entity.key,
|
|
68
66
|
entityType: entity.type,
|
|
69
67
|
relationType: reverseRelationMap[relatedEntity.relationType],
|
|
68
|
+
relatedEntityId: relatedEntity.id,
|
|
70
69
|
relatedEntityKey: relatedEntity.key,
|
|
71
70
|
relatedEntityType: relatedEntity.type,
|
|
72
71
|
},
|
|
@@ -5,8 +5,9 @@ import * as Sampler from 'openapi-sampler';
|
|
|
5
5
|
import type { CatalogEntityConfig } from '@redocly/config';
|
|
6
6
|
import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/core/types';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { useCatalogEntitySchema } from '@redocly/theme/core/hooks';
|
|
10
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
10
11
|
import { JsonViewer } from '@redocly/theme/components/JsonViewer/JsonViewer';
|
|
11
12
|
import { CopyButton } from '@redocly/theme/components/Buttons/CopyButton';
|
|
12
13
|
|
|
@@ -24,7 +25,6 @@ export type CatalogEntitySchemaProps = {
|
|
|
24
25
|
export function CatalogEntitySchema({
|
|
25
26
|
entity,
|
|
26
27
|
relatedEntity,
|
|
27
|
-
catalogConfig,
|
|
28
28
|
RedocSchema,
|
|
29
29
|
StoreProvider,
|
|
30
30
|
GraphqlTypeRenderer,
|
|
@@ -35,9 +35,6 @@ export function CatalogEntitySchema({
|
|
|
35
35
|
const { definition, parsedSchema, rawSchema } = useCatalogEntitySchema({ entity, relatedEntity });
|
|
36
36
|
const isGraphql = entity.metadata?.specType === 'graphql';
|
|
37
37
|
const graphqlSDL = entity?.metadata?.sdl;
|
|
38
|
-
const { getEntityDetailsLink } = useCatalogEntityDetails({
|
|
39
|
-
catalogConfig,
|
|
40
|
-
});
|
|
41
38
|
|
|
42
39
|
return (
|
|
43
40
|
<MetadataWrapper data-component-name="Catalog/CatalogEntity/CatalogEntitySchema">
|
|
@@ -54,9 +51,10 @@ export function CatalogEntitySchema({
|
|
|
54
51
|
onCopyClick={() =>
|
|
55
52
|
telemetry.sendCatalogEntitiesCopyDataSchemaClickedMessage([
|
|
56
53
|
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
...getBaseDataAttributes('catalogEntitiesCopyDataSchemaId', 'button'),
|
|
55
|
+
entityId: entity.id,
|
|
56
|
+
entityKey: entity.key,
|
|
57
|
+
entityType: entity.type,
|
|
60
58
|
},
|
|
61
59
|
])
|
|
62
60
|
}
|
|
@@ -12,7 +12,7 @@ import { FilterInput } from '@redocly/theme/components/Filter/FilterInput';
|
|
|
12
12
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
13
13
|
import { CheckboxIcon } from '@redocly/theme/icons/CheckboxIcon/CheckboxIcon';
|
|
14
14
|
import { CounterTag } from '@redocly/theme/components/Tags/CounterTag';
|
|
15
|
-
import { changeTextCasing } from '@redocly/theme/core/utils';
|
|
15
|
+
import { changeTextCasing, getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
16
16
|
import { Accordion } from '@redocly/theme/components/Accordion/Accordion';
|
|
17
17
|
|
|
18
18
|
export type CatalogFilterCheckboxesProps = FilterProps & {
|
|
@@ -104,9 +104,7 @@ export function CatalogFilterCheckboxes({
|
|
|
104
104
|
filter.toggleOption(value);
|
|
105
105
|
telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
|
|
106
106
|
{
|
|
107
|
-
|
|
108
|
-
object: 'checkbox',
|
|
109
|
-
uri: window.location.href,
|
|
107
|
+
...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
|
|
110
108
|
category: filter.property,
|
|
111
109
|
value: value,
|
|
112
110
|
},
|
|
@@ -11,6 +11,7 @@ import { Comment } from '@redocly/theme/components/Feedback/Comment';
|
|
|
11
11
|
import { Mood } from '@redocly/theme/components/Feedback/Mood';
|
|
12
12
|
import { Scale } from '@redocly/theme/components/Feedback/Scale';
|
|
13
13
|
import { DEFAULT_FEEDBACK_TYPE } from '@redocly/theme/core/constants';
|
|
14
|
+
import { getBaseDataAttributes } from '@redocly/theme/core/utils';
|
|
14
15
|
|
|
15
16
|
const feedbackComponents = {
|
|
16
17
|
rating: Rating,
|
|
@@ -58,7 +59,16 @@ export function Feedback(props: FeedbackProps & { path?: string }) {
|
|
|
58
59
|
settings={settings}
|
|
59
60
|
onSubmit={(values) => {
|
|
60
61
|
submitFeedback({ type, values, path });
|
|
61
|
-
telemetry.sendFeedbackMessage(
|
|
62
|
+
telemetry.sendFeedbackMessage([
|
|
63
|
+
{
|
|
64
|
+
...getBaseDataAttributes<
|
|
65
|
+
'feedbackFormId',
|
|
66
|
+
'feedbackForm',
|
|
67
|
+
'urn:redocly:realm:ui:feedbackForm:feedbackFormId'
|
|
68
|
+
>('feedbackFormId', 'feedbackForm'),
|
|
69
|
+
feedbackType: type,
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
62
72
|
}}
|
|
63
73
|
/>
|
|
64
74
|
</FeedbackWrapper>
|
|
@@ -64,8 +64,13 @@ export function useActiveHeading(
|
|
|
64
64
|
const headers = Array.from(allHeaders);
|
|
65
65
|
|
|
66
66
|
if (displayedHeadingsRef.current && displayedHeadingsRef.current.length > 0) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// Resolve targets by id so anchors that are not headings (e.g. numbered
|
|
68
|
+
// list items with a lifted headline) can be scrolled to and tracked.
|
|
69
|
+
return displayedHeadingsRef.current
|
|
70
|
+
.map((heading) =>
|
|
71
|
+
heading?.id ? allContent.querySelector<HTMLElement>(`[id="${heading.id}"]`) : null,
|
|
72
|
+
)
|
|
73
|
+
.filter((element): element is HTMLElement => element !== null);
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
return headers;
|
|
@@ -8,7 +8,7 @@ export const useTelemetryFallback = () => ({
|
|
|
8
8
|
sendCatalogEntitiesCopyDataSchemaClickedMessage: () => {},
|
|
9
9
|
sendCatalogEntitiesViewModeChangedMessage: () => {},
|
|
10
10
|
sendCatalogEntitiesRelatedEntitiesListSearchQueryMessage: () => {},
|
|
11
|
-
|
|
11
|
+
sendCatalogEntitiesRelatedEntitiesListSearchResultClickedMessage: () => {},
|
|
12
12
|
sendCatalogEntitiesListSearchQueryMessage: () => {},
|
|
13
13
|
sendCatalogEntitiesListSearchResultClickedMessage: () => {},
|
|
14
14
|
sendRedirectMessage: () => {},
|
package/src/core/styles/dark.ts
CHANGED
|
@@ -60,6 +60,17 @@ const badgesDarkMode = css`
|
|
|
60
60
|
// @tokens End
|
|
61
61
|
`
|
|
62
62
|
|
|
63
|
+
const numberedListDarkMode = css`
|
|
64
|
+
/**
|
|
65
|
+
* @tokens Markdown Numbered List
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
--md-numbered-list-marker-bg-color: var(--color-warm-grey-3); // @presenter Color
|
|
69
|
+
--md-numbered-list-marker-bg-color-hover: var(--color-warm-grey-4); // @presenter Color
|
|
70
|
+
|
|
71
|
+
// @tokens End
|
|
72
|
+
`
|
|
73
|
+
|
|
63
74
|
|
|
64
75
|
export const darkMode = css`
|
|
65
76
|
/* === Dark Theme Colors === */
|
|
@@ -352,6 +363,7 @@ export const darkMode = css`
|
|
|
352
363
|
${bannerDarkMode}
|
|
353
364
|
${admonitionDarkMode}
|
|
354
365
|
${badgesDarkMode}
|
|
366
|
+
${numberedListDarkMode}
|
|
355
367
|
${activeBrandPaletteDark}
|
|
356
368
|
${codeBlockDarkMode}
|
|
357
369
|
/**
|
|
@@ -29,6 +29,7 @@ import { productPicker } from '@redocly/theme/components/Product/variables';
|
|
|
29
29
|
import { markdown } from '@redocly/theme/components/Markdown/variables';
|
|
30
30
|
import { banner } from '@redocly/theme/components/Banner/variables';
|
|
31
31
|
import { markdownTabs } from '@redocly/theme/markdoc/components/Tabs/variables';
|
|
32
|
+
import { markdownNumberedList } from '@redocly/theme/markdoc/components/NumberedList/variables';
|
|
32
33
|
import { diagram } from '@redocly/theme/markdoc/components/Diagram/variables';
|
|
33
34
|
import { lastUpdated } from '@redocly/theme/components/LastUpdated/variables';
|
|
34
35
|
import { logo } from '@redocly/theme/components/Logo/variables';
|
|
@@ -1344,6 +1345,7 @@ export const styles = css<{ palette?: string }>`
|
|
|
1344
1345
|
${logo}
|
|
1345
1346
|
${markdown}
|
|
1346
1347
|
${markdownTabs}
|
|
1348
|
+
${markdownNumberedList}
|
|
1347
1349
|
${diagram}
|
|
1348
1350
|
${menu}
|
|
1349
1351
|
${mobileMenu}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import React, { createElement } from 'react';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { JSX, PropsWithChildren, ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';
|
|
7
|
+
import { LinkIcon } from '@redocly/theme/icons/LinkIcon/LinkIcon';
|
|
8
|
+
|
|
9
|
+
export const NumberedListType = {
|
|
10
|
+
ICON: 'icon',
|
|
11
|
+
NUMBER: 'number',
|
|
12
|
+
DOT: 'dot',
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type NumberedListType = (typeof NumberedListType)[keyof typeof NumberedListType];
|
|
16
|
+
|
|
17
|
+
export const NumberedListSize = {
|
|
18
|
+
SMALL: 'small',
|
|
19
|
+
MEDIUM: 'medium',
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
export type NumberedListSize = (typeof NumberedListSize)[keyof typeof NumberedListSize];
|
|
23
|
+
|
|
24
|
+
export type NumberedItemProps = PropsWithChildren<{
|
|
25
|
+
headline?: ReactNode;
|
|
26
|
+
anchorId?: string;
|
|
27
|
+
headlineLevel?: number;
|
|
28
|
+
icon?: string | ReactNode;
|
|
29
|
+
/* Internal use only: raw SVG content resolved for relative `.svg` icons */
|
|
30
|
+
iconRawContent?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
/* Injected by the parent NumberedList component */
|
|
33
|
+
type?: NumberedListType;
|
|
34
|
+
size?: NumberedListSize;
|
|
35
|
+
index?: number;
|
|
36
|
+
isLast?: boolean;
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
export function NumberedItem({
|
|
40
|
+
headline,
|
|
41
|
+
anchorId,
|
|
42
|
+
headlineLevel,
|
|
43
|
+
icon,
|
|
44
|
+
iconRawContent,
|
|
45
|
+
className,
|
|
46
|
+
type = NumberedListType.NUMBER,
|
|
47
|
+
size = NumberedListSize.MEDIUM,
|
|
48
|
+
index = 1,
|
|
49
|
+
isLast = true,
|
|
50
|
+
children,
|
|
51
|
+
}: NumberedItemProps): JSX.Element {
|
|
52
|
+
const isDot = type === NumberedListType.DOT;
|
|
53
|
+
const headlineTextId = anchorId ? `${anchorId}-heading-text` : undefined;
|
|
54
|
+
|
|
55
|
+
const marker = (
|
|
56
|
+
<Marker $type={type} $size={size} data-dot={isDot || undefined}>
|
|
57
|
+
{type === NumberedListType.ICON && (
|
|
58
|
+
<MarkerContent className="numbered-item-marker-content">
|
|
59
|
+
<GenericIcon icon={icon} rawContent={iconRawContent} />
|
|
60
|
+
</MarkerContent>
|
|
61
|
+
)}
|
|
62
|
+
{type === NumberedListType.NUMBER && (
|
|
63
|
+
<MarkerContent className="numbered-item-marker-content">{index}</MarkerContent>
|
|
64
|
+
)}
|
|
65
|
+
{anchorId && (
|
|
66
|
+
<MarkerLink className="numbered-item-marker-link" $isDot={isDot}>
|
|
67
|
+
<MarkerLinkIcon
|
|
68
|
+
aria-hidden="true"
|
|
69
|
+
focusable="false"
|
|
70
|
+
color="--md-numbered-list-marker-text-color"
|
|
71
|
+
/>
|
|
72
|
+
</MarkerLink>
|
|
73
|
+
)}
|
|
74
|
+
</Marker>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<NumberedItemWrapper
|
|
79
|
+
data-component-name="Markdoc/NumberedList/NumberedItem"
|
|
80
|
+
className={className}
|
|
81
|
+
id={anchorId}
|
|
82
|
+
$size={size}
|
|
83
|
+
$isDot={isDot}
|
|
84
|
+
>
|
|
85
|
+
<MarkerRail>
|
|
86
|
+
{anchorId ? (
|
|
87
|
+
<a
|
|
88
|
+
href={`#${anchorId}`}
|
|
89
|
+
{...(headline
|
|
90
|
+
? { 'aria-labelledby': headlineTextId }
|
|
91
|
+
: { 'aria-label': 'Link to this item' })}
|
|
92
|
+
>
|
|
93
|
+
{marker}
|
|
94
|
+
</a>
|
|
95
|
+
) : (
|
|
96
|
+
marker
|
|
97
|
+
)}
|
|
98
|
+
<Tail data-testid="numbered-item-tail" $isLast={isLast} />
|
|
99
|
+
</MarkerRail>
|
|
100
|
+
<NumberedItemContent>
|
|
101
|
+
{headline &&
|
|
102
|
+
createElement(
|
|
103
|
+
NumberedItemHeadline,
|
|
104
|
+
{ as: `h${headlineLevel ?? 3}` as keyof JSX.IntrinsicElements, id: headlineTextId },
|
|
105
|
+
headline,
|
|
106
|
+
)}
|
|
107
|
+
<NumberedItemBody>{children}</NumberedItemBody>
|
|
108
|
+
</NumberedItemContent>
|
|
109
|
+
</NumberedItemWrapper>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const markerSize = css<{ $size?: string }>`
|
|
114
|
+
${({ $size }) =>
|
|
115
|
+
$size === NumberedListSize.SMALL
|
|
116
|
+
? css`
|
|
117
|
+
width: var(--md-numbered-list-marker-small-size);
|
|
118
|
+
height: var(--md-numbered-list-marker-small-size);
|
|
119
|
+
--icon-width: var(--md-numbered-list-icon-small-size);
|
|
120
|
+
--icon-height: var(--md-numbered-list-icon-small-size);
|
|
121
|
+
`
|
|
122
|
+
: css`
|
|
123
|
+
width: var(--md-numbered-list-marker-medium-size);
|
|
124
|
+
height: var(--md-numbered-list-marker-medium-size);
|
|
125
|
+
--icon-width: var(--md-numbered-list-icon-medium-size);
|
|
126
|
+
--icon-height: var(--md-numbered-list-icon-medium-size);
|
|
127
|
+
`}
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
const Marker = styled.span<{ $type: string; $size: string }>`
|
|
131
|
+
position: relative;
|
|
132
|
+
display: flex;
|
|
133
|
+
align-items: center;
|
|
134
|
+
justify-content: center;
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
border-radius: 50%;
|
|
137
|
+
color: var(--md-numbered-list-marker-text-color);
|
|
138
|
+
font-size: var(--md-numbered-list-marker-font-size);
|
|
139
|
+
|
|
140
|
+
${({ $type }) =>
|
|
141
|
+
$type === NumberedListType.DOT
|
|
142
|
+
? css`
|
|
143
|
+
width: var(--md-numbered-list-dot-size);
|
|
144
|
+
height: var(--md-numbered-list-dot-size);
|
|
145
|
+
background-color: var(--text-color-primary);
|
|
146
|
+
`
|
|
147
|
+
: css`
|
|
148
|
+
${markerSize}
|
|
149
|
+
background-color: var(--md-numbered-list-marker-bg-color);
|
|
150
|
+
`}
|
|
151
|
+
`;
|
|
152
|
+
|
|
153
|
+
const MarkerContent = styled.span`
|
|
154
|
+
display: flex;
|
|
155
|
+
align-items: center;
|
|
156
|
+
justify-content: center;
|
|
157
|
+
`;
|
|
158
|
+
|
|
159
|
+
const MarkerLink = styled.span<{ $isDot?: boolean }>`
|
|
160
|
+
display: none;
|
|
161
|
+
align-items: center;
|
|
162
|
+
justify-content: center;
|
|
163
|
+
|
|
164
|
+
svg {
|
|
165
|
+
width: var(--icon-width, 16px);
|
|
166
|
+
height: var(--icon-height, 16px);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
${({ $isDot }) =>
|
|
170
|
+
$isDot &&
|
|
171
|
+
css`
|
|
172
|
+
position: absolute;
|
|
173
|
+
inset-inline-end: calc(100% + var(--md-numbered-list-dot-link-gap));
|
|
174
|
+
`}
|
|
175
|
+
`;
|
|
176
|
+
|
|
177
|
+
const MarkerLinkIcon = styled(LinkIcon)`
|
|
178
|
+
path:first-of-type {
|
|
179
|
+
fill: var(--md-numbered-list-marker-icon-bg-color);
|
|
180
|
+
}
|
|
181
|
+
`;
|
|
182
|
+
|
|
183
|
+
const MarkerRail = styled.span`
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-direction: column;
|
|
186
|
+
align-items: center;
|
|
187
|
+
align-self: stretch;
|
|
188
|
+
flex-shrink: 0;
|
|
189
|
+
|
|
190
|
+
a {
|
|
191
|
+
display: flex;
|
|
192
|
+
border-radius: 50%;
|
|
193
|
+
/* Overrides the global markdown link rule a:not([role='button']), which is more specific. */
|
|
194
|
+
text-decoration: none !important;
|
|
195
|
+
|
|
196
|
+
&:hover,
|
|
197
|
+
&:focus {
|
|
198
|
+
text-decoration: none !important;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
|
|
203
|
+
const Tail = styled.span<{ $isLast: boolean }>`
|
|
204
|
+
flex: 1 0 0;
|
|
205
|
+
min-height: var(--spacing-xs);
|
|
206
|
+
width: var(--md-numbered-list-tail-width);
|
|
207
|
+
background: ${({ $isLast }) =>
|
|
208
|
+
$isLast
|
|
209
|
+
? 'var(--md-numbered-list-tail-fade-gradient)'
|
|
210
|
+
: 'var(--md-numbered-list-tail-bg-color)'};
|
|
211
|
+
`;
|
|
212
|
+
|
|
213
|
+
const NumberedItemHeadline = styled.h3`
|
|
214
|
+
margin: 0;
|
|
215
|
+
color: var(--md-numbered-list-headline-text-color);
|
|
216
|
+
font-size: var(--md-numbered-list-headline-font-size);
|
|
217
|
+
font-weight: var(--md-numbered-list-headline-font-weight);
|
|
218
|
+
line-height: var(--md-numbered-list-headline-line-height);
|
|
219
|
+
`;
|
|
220
|
+
|
|
221
|
+
const NumberedItemBody = styled.div`
|
|
222
|
+
display: flex;
|
|
223
|
+
flex-direction: column;
|
|
224
|
+
gap: var(--md-numbered-list-body-gap);
|
|
225
|
+
color: var(--md-numbered-list-body-text-color);
|
|
226
|
+
font-size: var(--md-numbered-list-body-font-size);
|
|
227
|
+
|
|
228
|
+
> p {
|
|
229
|
+
margin: 0;
|
|
230
|
+
}
|
|
231
|
+
`;
|
|
232
|
+
|
|
233
|
+
const NumberedItemContent = styled.div`
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-direction: column;
|
|
236
|
+
gap: var(--spacing-unit);
|
|
237
|
+
flex: 1;
|
|
238
|
+
min-width: 0;
|
|
239
|
+
padding-bottom: var(--spacing-sm);
|
|
240
|
+
`;
|
|
241
|
+
|
|
242
|
+
const NumberedItemWrapper = styled.li<{ $size?: string; $isDot?: boolean }>`
|
|
243
|
+
display: flex;
|
|
244
|
+
gap: var(--md-numbered-list-gap);
|
|
245
|
+
align-items: stretch;
|
|
246
|
+
|
|
247
|
+
${({ $isDot }) =>
|
|
248
|
+
$isDot &&
|
|
249
|
+
css`
|
|
250
|
+
${MarkerRail} {
|
|
251
|
+
padding-top: var(--md-numbered-list-dot-rail-padding-top);
|
|
252
|
+
}
|
|
253
|
+
`}
|
|
254
|
+
|
|
255
|
+
&:last-child ${NumberedItemContent} {
|
|
256
|
+
padding-bottom: 0;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
&:hover,
|
|
260
|
+
&:focus-within {
|
|
261
|
+
${Marker} {
|
|
262
|
+
background-color: ${({ $isDot }) =>
|
|
263
|
+
$isDot ? 'var(--text-color-primary)' : 'var(--md-numbered-list-marker-bg-color-hover)'};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
a ${Marker}:not([data-dot]) .numbered-item-marker-content {
|
|
267
|
+
display: none;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
a ${Marker} .numbered-item-marker-link {
|
|
271
|
+
display: flex;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
`;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { JSX, PropsWithChildren } from 'react';
|
|
5
|
+
|
|
6
|
+
export type NumberedListProps = PropsWithChildren<{
|
|
7
|
+
className?: string;
|
|
8
|
+
}>;
|
|
9
|
+
|
|
10
|
+
export function NumberedList({ className, children }: NumberedListProps): JSX.Element | null {
|
|
11
|
+
if (React.Children.count(children) === 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<NumberedListWrapper
|
|
17
|
+
data-component-name="Markdoc/NumberedList/NumberedList"
|
|
18
|
+
className={className}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
</NumberedListWrapper>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const NumberedListWrapper = styled.ol`
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
margin: var(--md-numbered-list-margin);
|
|
29
|
+
padding: 0;
|
|
30
|
+
list-style: none;
|
|
31
|
+
|
|
32
|
+
&& {
|
|
33
|
+
& > li:not(:last-child) {
|
|
34
|
+
margin-bottom: 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`;
|