Skip to content

Commit 104d824

Browse files
committed
fix: add examples in property
1 parent 68d2e5d commit 104d824

File tree

4 files changed

+155
-39
lines changed

4 files changed

+155
-39
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* ============================================================================
2+
* Copyright (c) Palo Alto Networks
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* ========================================================================== */
7+
8+
import React from "react";
9+
10+
import { ExampleObject } from "@theme/ParamsItem";
11+
import SchemaTabs from "@theme/SchemaTabs";
12+
import TabItem from "@theme/TabItem";
13+
14+
/**
15+
* Format example value
16+
*
17+
* @param example
18+
* @returns
19+
*/
20+
const formatExample = (example: any) => {
21+
if (typeof example === "object" && example !== null) {
22+
return JSON.stringify(example);
23+
}
24+
return String(example);
25+
};
26+
27+
/**
28+
* Render string examples
29+
*
30+
* @param examples
31+
* @returns
32+
*/
33+
export function renderStringExamples(
34+
examples: string[] | undefined
35+
): React.JSX.Element | undefined {
36+
if (examples && examples.length > 0) {
37+
// If there's only one example, display it without tabs
38+
if (examples.length === 1) {
39+
return (
40+
<div>
41+
<strong>Example: </strong>
42+
<span>
43+
<code>{formatExample(examples[0])}</code>
44+
</span>
45+
</div>
46+
);
47+
}
48+
49+
// Multiple examples - use tabs
50+
return (
51+
<div>
52+
<strong>Examples:</strong>
53+
<SchemaTabs>
54+
{examples.map((example, index) => (
55+
// @ts-ignore
56+
<TabItem
57+
value={`Example ${index + 1}`}
58+
label={`Example ${index + 1}`}
59+
key={`Example ${index + 1}`}
60+
>
61+
<p>
62+
<strong>Example: </strong>
63+
<code>{formatExample(example)}</code>
64+
</p>
65+
</TabItem>
66+
))}
67+
</SchemaTabs>
68+
</div>
69+
);
70+
}
71+
return undefined;
72+
}
73+
74+
export const renderExamplesRecord = (
75+
examples: Record<string, ExampleObject>
76+
) => {
77+
const exampleEntries = Object.entries(examples);
78+
// If there's only one example, display it without tabs
79+
if (exampleEntries.length === 1) {
80+
const firstExample = exampleEntries[0][1];
81+
if (!firstExample) {
82+
return undefined;
83+
}
84+
return (
85+
<div>
86+
<strong>Example: </strong>
87+
<span>
88+
<code>{formatExample(firstExample.value)}</code>
89+
</span>
90+
</div>
91+
);
92+
}
93+
94+
return (
95+
<>
96+
<strong>Examples:</strong>
97+
<SchemaTabs>
98+
{exampleEntries.map(([exampleName, exampleProperties]) =>
99+
renderExampleObject(exampleName, exampleProperties)
100+
)}
101+
</SchemaTabs>
102+
</>
103+
);
104+
};
105+
106+
/**
107+
* Render example object
108+
*
109+
* @param exampleName
110+
* @param exampleProperties
111+
* @returns
112+
*/
113+
const renderExampleObject = (
114+
exampleName: string,
115+
exampleProperties: ExampleObject
116+
) => {
117+
return (
118+
// @ts-ignore
119+
<TabItem value={exampleName} label={exampleName}>
120+
{exampleProperties.summary && <p>{exampleProperties.summary}</p>}
121+
{exampleProperties.description && (
122+
<p>
123+
<strong>Description: </strong>
124+
<span>{exampleProperties.description}</span>
125+
</p>
126+
)}
127+
<p>
128+
<strong>Example: </strong>
129+
<code>{formatExample(exampleProperties.value)}</code>
130+
</p>
131+
</TabItem>
132+
);
133+
};

packages/docusaurus-theme-openapi-docs/src/theme/ParamsItem/index.tsx

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import React from "react";
99

10+
import { renderExamplesRecord, renderStringExamples } from "@theme/Example";
1011
import Markdown from "@theme/Markdown";
1112
import SchemaTabs from "@theme/SchemaTabs";
1213
import TabItem from "@theme/TabItem";
@@ -28,7 +29,7 @@ export interface Props {
2829
param: {
2930
description: string;
3031
example: any;
31-
examples: Record<string, ExampleObject>;
32+
examples: Record<string, ExampleObject> | undefined;
3233
name: string;
3334
required: boolean;
3435
deprecated: boolean;
@@ -53,19 +54,14 @@ ${enumDescriptions
5354
};
5455

5556
function ParamsItem({ param, ...rest }: Props) {
56-
const {
57-
description,
58-
example,
59-
examples,
60-
name,
61-
required,
62-
deprecated,
63-
enumDescriptions,
64-
} = param;
57+
const { description, name, required, deprecated, enumDescriptions } = param;
6558

6659
let schema = param.schema;
6760
let defaultValue: string | undefined;
6861

62+
let examples = param.examples || (schema?.examples as any[] | undefined);
63+
let example = param.example || schema?.example;
64+
6965
if (!schema) {
7066
schema = { type: "any" };
7167
}
@@ -140,35 +136,18 @@ function ParamsItem({ param, ...rest }: Props) {
140136
const renderExample = guard(toString(example), (example) => (
141137
<div>
142138
<strong>Example: </strong>
143-
{example}
139+
<code>{example}</code>
144140
</div>
145141
));
146142

147143
const renderExamples = guard(examples, (examples) => {
148-
const exampleEntries = Object.entries(examples);
149-
return (
150-
<>
151-
<strong>Examples:</strong>
152-
<SchemaTabs>
153-
{exampleEntries.map(([exampleName, exampleProperties]) => (
154-
// @ts-ignore
155-
<TabItem value={exampleName} label={exampleName}>
156-
{exampleProperties.summary && <p>{exampleProperties.summary}</p>}
157-
{exampleProperties.description && (
158-
<p>
159-
<strong>Description: </strong>
160-
<span>{exampleProperties.description}</span>
161-
</p>
162-
)}
163-
<p>
164-
<strong>Example: </strong>
165-
<code>{exampleProperties.value}</code>
166-
</p>
167-
</TabItem>
168-
))}
169-
</SchemaTabs>
170-
</>
171-
);
144+
if (!examples) {
145+
return undefined;
146+
}
147+
if (Array.isArray(examples)) {
148+
return renderStringExamples(examples);
149+
}
150+
return renderExamplesRecord(examples);
172151
});
173152

174153
return (

packages/docusaurus-theme-openapi-docs/src/theme/ResponseSchema/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ const ResponseSchemaComponent: React.FC<Props> = ({
5454
return (
5555
<MimeTabs className="openapi-tabs__mime" schemaType="response">
5656
{mimeTypes.map((mimeType: any) => {
57-
const responseExamples = body.content![mimeType].examples;
58-
const responseExample = body.content![mimeType].example;
59-
const firstBody: any =
60-
body.content![mimeType].schema ?? body.content![mimeType];
57+
const mediaTypeObject = body.content?.[mimeType];
58+
const responseExamples = mediaTypeObject?.examples;
59+
const responseExample = mediaTypeObject?.example;
60+
const firstBody = mediaTypeObject?.schema ?? mediaTypeObject;
6161

6262
if (
6363
firstBody === undefined &&

packages/docusaurus-theme-openapi-docs/src/theme/SchemaItem/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import React, { ReactNode } from "react";
99

10+
import { renderStringExamples } from "@theme/Example";
1011
import Markdown from "@theme/Markdown";
1112
import clsx from "clsx";
1213

@@ -63,6 +64,7 @@ export default function SchemaItem(props: Props) {
6364
let schemaDescription;
6465
let defaultValue: string | undefined;
6566
let example: string | undefined;
67+
let examples: string[] | undefined;
6668
let nullable;
6769
let enumDescriptions: [string, string][] = [];
6870
let constValue: string | undefined;
@@ -73,6 +75,7 @@ export default function SchemaItem(props: Props) {
7375
enumDescriptions = transformEnumDescriptions(schema["x-enumDescriptions"]);
7476
defaultValue = schema.default;
7577
example = schema.example;
78+
examples = schema.examples;
7679
nullable =
7780
schema.nullable ||
7881
(Array.isArray(schema.type) && schema.type.includes("null")); // support JSON Schema nullable
@@ -213,6 +216,7 @@ export default function SchemaItem(props: Props) {
213216
{renderConstValue()}
214217
{renderDefaultValue()}
215218
{renderExample()}
219+
{renderStringExamples(examples)}
216220
{collapsibleSchemaContent ?? collapsibleSchemaContent}
217221
</div>
218222
);

0 commit comments

Comments
 (0)