docusaurus-theme-openapi-docs 4.1.0 → 4.2.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.
Files changed (43) hide show
  1. package/lib/theme/ApiExplorer/CodeSnippets/index.js +2 -1
  2. package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +50 -0
  3. package/lib/theme/ApiItem/Layout/index.js +6 -2
  4. package/lib/theme/ApiItem/index.js +15 -4
  5. package/lib/theme/ApiTabs/_ApiTabs.scss +0 -1
  6. package/lib/theme/ArrayBrackets/index.d.ts +3 -0
  7. package/lib/theme/ArrayBrackets/index.js +50 -0
  8. package/lib/theme/ParamsDetails/index.d.ts +6 -0
  9. package/lib/theme/ParamsDetails/index.js +134 -0
  10. package/lib/theme/ParamsItem/index.d.ts +1 -0
  11. package/lib/theme/ParamsItem/index.js +10 -6
  12. package/lib/theme/RequestSchema/index.d.ts +15 -0
  13. package/lib/theme/RequestSchema/index.js +235 -0
  14. package/lib/theme/ResponseExamples/index.d.ts +48 -0
  15. package/lib/theme/ResponseExamples/index.js +290 -0
  16. package/lib/theme/ResponseSchema/index.d.ts +15 -0
  17. package/lib/theme/ResponseSchema/index.js +206 -0
  18. package/lib/theme/Schema/index.d.ts +8 -0
  19. package/lib/theme/Schema/index.js +879 -0
  20. package/lib/theme/SchemaItem/index.d.ts +8 -8
  21. package/lib/theme/SchemaItem/index.js +9 -5
  22. package/lib/theme/SkeletonLoader/index.d.ts +6 -0
  23. package/lib/theme/SkeletonLoader/index.js +20 -0
  24. package/lib/theme/StatusCodes/index.d.ts +9 -0
  25. package/lib/theme/StatusCodes/index.js +78 -0
  26. package/lib/theme/styles.scss +56 -9
  27. package/package.json +6 -5
  28. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +2 -1
  29. package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +50 -0
  30. package/src/theme/ApiItem/Layout/index.tsx +5 -2
  31. package/src/theme/ApiItem/index.tsx +14 -2
  32. package/src/theme/ApiTabs/_ApiTabs.scss +0 -1
  33. package/src/theme/ArrayBrackets/index.tsx +37 -0
  34. package/src/theme/ParamsDetails/index.tsx +88 -0
  35. package/src/theme/ParamsItem/index.tsx +10 -7
  36. package/src/theme/RequestSchema/index.tsx +164 -0
  37. package/src/theme/ResponseExamples/index.tsx +290 -0
  38. package/src/theme/ResponseSchema/index.tsx +151 -0
  39. package/src/theme/Schema/index.tsx +928 -0
  40. package/src/theme/SchemaItem/index.tsx +15 -13
  41. package/src/theme/SkeletonLoader/index.tsx +18 -0
  42. package/src/theme/StatusCodes/index.tsx +72 -0
  43. package/src/theme/styles.scss +56 -9
@@ -1,12 +1,12 @@
1
1
  import React, { ReactNode } from "react";
2
2
  export interface Props {
3
- children: ReactNode;
4
- collapsible: boolean;
5
- name: string;
6
- qualifierMessage: string | undefined;
7
- required: boolean;
8
- schemaName: string;
9
- schema: any;
10
- discriminator: boolean;
3
+ children?: ReactNode;
4
+ collapsible?: boolean;
5
+ name?: string;
6
+ qualifierMessage?: string | undefined;
7
+ required?: boolean;
8
+ schemaName?: string;
9
+ schema?: any;
10
+ discriminator?: boolean;
11
11
  }
12
12
  export default function SchemaItem(props: Props): React.JSX.Element;
@@ -88,11 +88,15 @@ function SchemaItem(props) {
88
88
  const renderEnumDescriptions = (0, utils_1.guard)(
89
89
  getEnumDescriptionMarkdown(enumDescriptions),
90
90
  (value) => {
91
- return react_1.default.createElement(react_markdown_1.default, {
92
- remarkPlugins: [remark_gfm_1.default],
93
- rehypePlugins: [rehype_raw_1.default],
94
- children: value,
95
- });
91
+ return react_1.default.createElement(
92
+ "div",
93
+ { style: { marginTop: ".5rem" } },
94
+ react_1.default.createElement(react_markdown_1.default, {
95
+ remarkPlugins: [remark_gfm_1.default],
96
+ rehypePlugins: [rehype_raw_1.default],
97
+ children: value,
98
+ })
99
+ );
96
100
  }
97
101
  );
98
102
  const renderSchemaDescription = (0, utils_1.guard)(
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ interface Props {
3
+ size?: "sm" | "md" | "lg";
4
+ }
5
+ declare const SkeletonLoader: React.FC<Props>;
6
+ export default SkeletonLoader;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ var __importDefault =
9
+ (this && this.__importDefault) ||
10
+ function (mod) {
11
+ return mod && mod.__esModule ? mod : { default: mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const react_1 = __importDefault(require("react"));
15
+ const SkeletonLoader = (props) => {
16
+ return react_1.default.createElement("div", {
17
+ className: `openapi-skeleton ${props.size ?? "md"}`,
18
+ });
19
+ };
20
+ exports.default = SkeletonLoader;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { ApiItem } from "docusaurus-plugin-openapi-docs/lib/types";
3
+ interface Props {
4
+ id?: string;
5
+ label?: string;
6
+ responses: ApiItem["responses"];
7
+ }
8
+ declare const StatusCodes: React.FC<Props>;
9
+ export default StatusCodes;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ var __importDefault =
9
+ (this && this.__importDefault) ||
10
+ function (mod) {
11
+ return mod && mod.__esModule ? mod : { default: mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const react_1 = __importDefault(require("react"));
15
+ const ApiTabs_1 = __importDefault(require("@theme/ApiTabs"));
16
+ const Details_1 = __importDefault(require("@theme/Details"));
17
+ const ResponseExamples_1 = require("@theme/ResponseExamples");
18
+ const ResponseSchema_1 = __importDefault(require("@theme/ResponseSchema"));
19
+ const TabItem_1 = __importDefault(require("@theme/TabItem"));
20
+ const createDescription_1 = require("docusaurus-plugin-openapi-docs/lib/markdown/createDescription");
21
+ const StatusCodes = ({ label, id, responses }) => {
22
+ if (!responses) return null;
23
+ const codes = Object.keys(responses);
24
+ if (codes.length === 0) return null;
25
+ return react_1.default.createElement(
26
+ ApiTabs_1.default,
27
+ { label: label, id: id },
28
+ codes.map((code) => {
29
+ const response = responses[code];
30
+ const responseHeaders = response.headers;
31
+ return (
32
+ // @ts-ignore
33
+ react_1.default.createElement(
34
+ TabItem_1.default,
35
+ { key: code, label: code, value: code },
36
+ react_1.default.createElement(
37
+ "div",
38
+ null,
39
+ response.description &&
40
+ react_1.default.createElement(
41
+ "div",
42
+ { style: { marginTop: ".5rem", marginBottom: ".5rem" } },
43
+ (0, createDescription_1.createDescription)(response.description)
44
+ )
45
+ ),
46
+ responseHeaders &&
47
+ react_1.default.createElement(
48
+ Details_1.default,
49
+ {
50
+ className: "openapi-markdown__details",
51
+ "data-collapsed": true,
52
+ open: false,
53
+ style: { textAlign: "left", marginBottom: "1rem" },
54
+ summary: react_1.default.createElement(
55
+ "summary",
56
+ null,
57
+ react_1.default.createElement(
58
+ "strong",
59
+ null,
60
+ "Response Headers"
61
+ )
62
+ ),
63
+ },
64
+ react_1.default.createElement(
65
+ ResponseExamples_1.ResponseHeaders,
66
+ { responseHeaders: responseHeaders }
67
+ )
68
+ ),
69
+ react_1.default.createElement(ResponseSchema_1.default, {
70
+ title: "Schema",
71
+ body: { content: response.content },
72
+ })
73
+ )
74
+ );
75
+ })
76
+ );
77
+ };
78
+ exports.default = StatusCodes;
@@ -81,6 +81,7 @@
81
81
  --openapi-explorer-padding-input: 0.5rem;
82
82
  --openapi-explorer-border-color: var(--ifm-toc-border-color);
83
83
  --openapi-explorer-caret-bg: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path></svg>');
84
+ --openapi-skeleton-background: var(--ifm-color-emphasis-100);
84
85
  }
85
86
 
86
87
  [data-theme="dark"] {
@@ -92,16 +93,16 @@
92
93
  height: 100%;
93
94
  }
94
95
 
95
- @media (min-width: 997px) {
96
- .docItemCol {
97
- max-width: 75% !important;
98
- }
96
+ // @media (min-width: 997px) {
97
+ // .docItemCol {
98
+ // max-width: 75% !important;
99
+ // }
99
100
 
100
- /* Prevent hydration FOUC, as the mobile TOC needs to be server-rendered */
101
- .tocMobile {
102
- display: none;
103
- }
104
- }
101
+ // /* Prevent hydration FOUC, as the mobile TOC needs to be server-rendered */
102
+ // .tocMobile {
103
+ // display: none;
104
+ // }
105
+ // }
105
106
 
106
107
  /* Begin OpenAPI theme styles */
107
108
  // [data-theme="dark"] {
@@ -160,6 +161,52 @@
160
161
  border-right: thin solid var(--ifm-toc-border-color);
161
162
  }
162
163
 
164
+ @media (max-width: 997px) {
165
+ .schema {
166
+ margin-bottom: 1rem;
167
+ }
168
+ }
169
+
163
170
  .openapi-tabs__heading {
164
171
  margin-bottom: 1rem;
165
172
  }
173
+
174
+ /* Loading Skeleton */
175
+ @keyframes pulsing {
176
+ 0% {
177
+ opacity: 1;
178
+ background-color: var(--ifm-color-emphasis-100);
179
+ }
180
+ 50% {
181
+ opacity: 0.6;
182
+ background-color: var(--ifm-toc-border-color);
183
+ }
184
+ 100% {
185
+ opacity: 1;
186
+ background-color: var(--ifm-color-emphasis-100);
187
+ }
188
+ }
189
+
190
+ .openapi-skeleton {
191
+ animation: pulsing 2s infinite ease-in-out;
192
+ }
193
+
194
+ /* Loading Skeleton */
195
+ .openapi-skeleton {
196
+ border-radius: var(--ifm-pre-border-radius);
197
+ background-color: var(--openapi-skeleton-background);
198
+ max-width: 100%;
199
+ margin: 1rem auto;
200
+ }
201
+
202
+ .openapi-skeleton.sm {
203
+ height: 100px;
204
+ }
205
+
206
+ .openapi-skeleton.md {
207
+ height: 350px;
208
+ }
209
+
210
+ .openapi-skeleton.lg {
211
+ height: 96.5%;
212
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-theme-openapi-docs",
3
3
  "description": "OpenAPI theme for Docusaurus.",
4
- "version": "4.1.0",
4
+ "version": "4.2.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -39,10 +39,11 @@
39
39
  "@docusaurus/theme-common": "^3.5.0",
40
40
  "@hookform/error-message": "^2.0.1",
41
41
  "@reduxjs/toolkit": "^1.7.1",
42
+ "allof-merge": "^0.6.6",
42
43
  "clsx": "^1.1.1",
43
44
  "copy-text-to-clipboard": "^3.1.0",
44
45
  "crypto-js": "^4.1.1",
45
- "docusaurus-plugin-openapi-docs": "^4.1.0",
46
+ "docusaurus-plugin-openapi-docs": "^4.2.0",
46
47
  "docusaurus-plugin-sass": "^0.2.3",
47
48
  "file-saver": "^2.0.5",
48
49
  "lodash": "^4.17.20",
@@ -58,8 +59,8 @@
58
59
  "react-redux": "^7.2.0",
59
60
  "rehype-raw": "^6.1.1",
60
61
  "remark-gfm": "3.0.1",
61
- "sass": "^1.58.1",
62
- "sass-loader": "^13.3.2",
62
+ "sass": "^1.80.4",
63
+ "sass-loader": "^16.0.2",
63
64
  "webpack": "^5.61.0",
64
65
  "xml-formatter": "^2.6.1"
65
66
  },
@@ -70,5 +71,5 @@
70
71
  "engines": {
71
72
  "node": ">=14"
72
73
  },
73
- "gitHead": "4e771d309f6defe395449b26cc3c65814d72cbcc"
74
+ "gitHead": "e7295a8aa6f3fab5ccc4f8f9ad0e6c33d785aa16"
74
75
  }
@@ -180,7 +180,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
180
180
  ]);
181
181
  // no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
182
182
  useEffect(function onSelectedVariantUpdate() {
183
- if (selectedVariant && selectedVariant !== language.variant) {
183
+ if (selectedVariant && selectedVariant !== language?.variant) {
184
184
  const postmanRequest = buildPostmanRequest(postman, {
185
185
  queryParams,
186
186
  pathParams,
@@ -211,6 +211,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
211
211
  // eslint-disable-next-line react-hooks/exhaustive-deps
212
212
  useEffect(function onSelectedSampleUpdate() {
213
213
  if (
214
+ language &&
214
215
  language.samples &&
215
216
  language.samplesSources &&
216
217
  selectedSample &&
@@ -436,6 +436,56 @@ body[class="ReactModal__Body--open"] {
436
436
  }
437
437
  }
438
438
 
439
+ .openapi-tabs__code-item--http {
440
+ color: var(--ifm-color-gray-500);
441
+ display: flex;
442
+ align-items: center;
443
+ justify-content: center;
444
+ position: relative;
445
+
446
+ &::after {
447
+ content: "";
448
+ display: inline-block;
449
+ width: 32px; /* Explicitly setting width to 32 pixels */
450
+ height: 32px; /* Explicitly setting height to 32 pixels */
451
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyIDIyTDggMTZMMTIgMTBNMjAgMjJMMjQgMTZMIDIwIDEwIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
452
+ background-size: contain;
453
+ background-repeat: no-repeat;
454
+ background-position: center; /* Center the SVG */
455
+ margin-top: 0.5rem;
456
+ }
457
+
458
+ &.active {
459
+ box-shadow: 0 0 0 3px var(--opeanpi-code-tab-shadow-color-http);
460
+ border-color: var(--openapi-code-tab-border-color-http);
461
+ }
462
+ }
463
+
464
+ .openapi-tabs__code-item--shell {
465
+ color: var(--ifm-color-gray-500);
466
+ display: flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ position: relative;
470
+
471
+ &::after {
472
+ content: "";
473
+ display: inline-block;
474
+ width: 32px; /* Explicitly setting width to 32 pixels */
475
+ height: 32px; /* Explicitly setting height to 32 pixels */
476
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyIDIyTDggMTZMMTIgMTBNMjAgMjJMMjQgMTZMIDIwIDEwIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4=");
477
+ background-size: contain;
478
+ background-repeat: no-repeat;
479
+ background-position: center; /* Center the SVG */
480
+ margin-top: 0.5rem;
481
+ }
482
+
483
+ &.active {
484
+ box-shadow: 0 0 0 3px var(--opeanpi-code-tab-shadow-color-shell);
485
+ border-color: var(--openapi-code-tab-border-color-shell);
486
+ }
487
+ }
488
+
439
489
  @media only screen and (min-width: 768px) and (max-width: 996px) {
440
490
  .openapi-tabs__code-list {
441
491
  justify-content: space-around;
@@ -52,6 +52,7 @@ export default function DocItemLayout({ children }: Props): JSX.Element {
52
52
  const { metadata } = useDoc();
53
53
  const { frontMatter } = useDoc();
54
54
  const api = frontMatter.api;
55
+ const schema = frontMatter.schema;
55
56
  return (
56
57
  <div className="row">
57
58
  <div className={clsx("col", !docTOC.hidden && styles.docItemCol)}>
@@ -64,13 +65,15 @@ export default function DocItemLayout({ children }: Props): JSX.Element {
64
65
  {docTOC.mobile}
65
66
  <DocItemContent>{children}</DocItemContent>
66
67
  <div className="row">
67
- <div className={clsx("col", api ? "col--7" : "col--12")}>
68
+ <div
69
+ className={clsx("col", api || schema ? "col--7" : "col--12")}
70
+ >
68
71
  <DocItemFooter />
69
72
  </div>
70
73
  </div>
71
74
  </article>
72
75
  <div className="row">
73
- <div className={clsx("col", api ? "col--7" : "col--12")}>
76
+ <div className={clsx("col", api || schema ? "col--7" : "col--12")}>
74
77
  <DocItemPaginator />
75
78
  </div>
76
79
  </div>
@@ -18,8 +18,10 @@ import useIsBrowser from "@docusaurus/useIsBrowser";
18
18
  import { createAuth } from "@theme/ApiExplorer/Authorization/slice";
19
19
  import { createPersistanceMiddleware } from "@theme/ApiExplorer/persistanceMiddleware";
20
20
  import DocItemLayout from "@theme/ApiItem/Layout";
21
+ import CodeBlock from "@theme/CodeBlock";
21
22
  import type { Props } from "@theme/DocItem";
22
23
  import DocItemMetadata from "@theme/DocItem/Metadata";
24
+ import SkeletonLoader from "@theme/SkeletonLoader";
23
25
  import clsx from "clsx";
24
26
  import { ServerObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
25
27
  import { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
@@ -46,6 +48,10 @@ interface SchemaFrontMatter extends DocFrontMatter {
46
48
  readonly schema?: boolean;
47
49
  }
48
50
 
51
+ interface SampleFrontMatter extends DocFrontMatter {
52
+ readonly sample?: any;
53
+ }
54
+
49
55
  // @ts-ignore
50
56
  export default function ApiItem(props: Props): JSX.Element {
51
57
  const docHtmlClassName = `docs-doc-id-${props.content.metadata.id}`;
@@ -54,6 +60,7 @@ export default function ApiItem(props: Props): JSX.Element {
54
60
  const { info_path: infoPath } = frontMatter as DocFrontMatter;
55
61
  let { api } = frontMatter as ApiFrontMatter;
56
62
  const { schema } = frontMatter as SchemaFrontMatter;
63
+ const { sample } = frontMatter as SampleFrontMatter;
57
64
  // decompress and parse
58
65
  if (api) {
59
66
  try {
@@ -152,7 +159,7 @@ export default function ApiItem(props: Props): JSX.Element {
152
159
  <MDXComponent />
153
160
  </div>
154
161
  <div className="col col--5 openapi-right-panel__container">
155
- <BrowserOnly fallback={<div>Loading...</div>}>
162
+ <BrowserOnly fallback={<SkeletonLoader size="lg" />}>
156
163
  {() => {
157
164
  return <ApiExplorer item={api} infoPath={infoPath} />;
158
165
  }}
@@ -171,9 +178,14 @@ export default function ApiItem(props: Props): JSX.Element {
171
178
  <DocItemMetadata />
172
179
  <DocItemLayout>
173
180
  <div className={clsx("row", "theme-api-markdown")}>
174
- <div className="col col--12">
181
+ <div className="col col--7 openapi-left-panel__container schema">
175
182
  <MDXComponent />
176
183
  </div>
184
+ <div className="col col--5 openapi-right-panel__container">
185
+ <CodeBlock language="json" title={`${frontMatter.title}`}>
186
+ {JSON.stringify(sample, null, 2)}
187
+ </CodeBlock>
188
+ </div>
177
189
  </div>
178
190
  </DocItemLayout>
179
191
  </HtmlClassNameProvider>
@@ -6,7 +6,6 @@
6
6
  * ========================================================================== */
7
7
  .openapi-tabs__container {
8
8
  margin-left: -1px;
9
- margin-bottom: var(--ifm-leading);
10
9
  }
11
10
 
12
11
  .openapi-tabs__response-header {
@@ -0,0 +1,37 @@
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
+ export const OpeningArrayBracket = () => (
11
+ <li>
12
+ <div
13
+ style={{
14
+ fontSize: "var(--ifm-code-font-size)",
15
+ opacity: 0.6,
16
+ marginLeft: "-.5rem",
17
+ paddingBottom: ".5rem",
18
+ }}
19
+ >
20
+ Array [
21
+ </div>
22
+ </li>
23
+ );
24
+
25
+ export const ClosingArrayBracket = () => (
26
+ <li>
27
+ <div
28
+ style={{
29
+ fontSize: "var(--ifm-code-font-size)",
30
+ opacity: 0.6,
31
+ marginLeft: "-.5rem",
32
+ }}
33
+ >
34
+ ]
35
+ </div>
36
+ </li>
37
+ );
@@ -0,0 +1,88 @@
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, { Suspense } from "react";
9
+
10
+ import BrowserOnly from "@docusaurus/BrowserOnly";
11
+ import Details from "@theme/Details";
12
+ import ParamsItem from "@theme/ParamsItem";
13
+ import SkeletonLoader from "@theme/SkeletonLoader";
14
+
15
+ interface Props {
16
+ parameters: any[];
17
+ }
18
+
19
+ const ParamsDetailsComponent: React.FC<Props> = ({ parameters }) => {
20
+ const types = ["path", "query", "header", "cookie"];
21
+
22
+ return (
23
+ <>
24
+ {types.map((type) => {
25
+ const params = parameters?.filter((param: any) => param?.in === type);
26
+
27
+ if (!params || params.length === 0) {
28
+ return null;
29
+ }
30
+
31
+ const summaryElement = (
32
+ <summary>
33
+ <h3 className="openapi-markdown__details-summary-header-params">
34
+ {`${type.charAt(0).toUpperCase() + type.slice(1)} Parameters`}
35
+ </h3>
36
+ </summary>
37
+ );
38
+
39
+ return (
40
+ <Details
41
+ key={type}
42
+ className="openapi-markdown__details"
43
+ style={{ marginBottom: "1rem" }}
44
+ data-collapsed={false}
45
+ open={true}
46
+ summary={summaryElement}
47
+ >
48
+ <ul>
49
+ {params.map((param: any, index: number) => (
50
+ <ParamsItem
51
+ key={index}
52
+ className="paramsItem"
53
+ param={{
54
+ ...param,
55
+ enumDescriptions: Object.entries(
56
+ param?.schema?.["x-enumDescriptions"] ??
57
+ param?.schema?.items?.["x-enumDescriptions"] ??
58
+ {}
59
+ ),
60
+ }}
61
+ />
62
+ ))}
63
+ </ul>
64
+ </Details>
65
+ );
66
+ })}
67
+ </>
68
+ );
69
+ };
70
+
71
+ const ParamsDetails: React.FC<Props> = (props) => {
72
+ return (
73
+ <BrowserOnly fallback={<SkeletonLoader size="sm" />}>
74
+ {() => {
75
+ const LazyComponent = React.lazy(() =>
76
+ Promise.resolve({ default: ParamsDetailsComponent })
77
+ );
78
+ return (
79
+ <Suspense fallback={null}>
80
+ <LazyComponent {...props} />
81
+ </Suspense>
82
+ );
83
+ }}
84
+ </BrowserOnly>
85
+ );
86
+ };
87
+
88
+ export default ParamsDetails;
@@ -32,6 +32,7 @@ export interface ExampleObject {
32
32
  }
33
33
 
34
34
  export interface Props {
35
+ className: string;
35
36
  param: {
36
37
  description: string;
37
38
  example: any;
@@ -106,7 +107,7 @@ function ParamsItem({ param, ...rest }: Props) {
106
107
  ));
107
108
 
108
109
  const renderDescription = guard(description, (description) => (
109
- <div>
110
+ <>
110
111
  <ReactMarkdown
111
112
  children={createDescription(description)}
112
113
  components={{
@@ -123,18 +124,20 @@ function ParamsItem({ param, ...rest }: Props) {
123
124
  }}
124
125
  rehypePlugins={[rehypeRaw]}
125
126
  />
126
- </div>
127
+ </>
127
128
  ));
128
129
 
129
130
  const renderEnumDescriptions = guard(
130
131
  getEnumDescriptionMarkdown(enumDescriptions),
131
132
  (value) => {
132
133
  return (
133
- <ReactMarkdown
134
- rehypePlugins={[rehypeRaw]}
135
- remarkPlugins={[remarkGfm]}
136
- children={value}
137
- />
134
+ <div style={{ marginTop: ".5rem" }}>
135
+ <ReactMarkdown
136
+ rehypePlugins={[rehypeRaw]}
137
+ remarkPlugins={[remarkGfm]}
138
+ children={value}
139
+ />
140
+ </div>
138
141
  );
139
142
  }
140
143
  );