docusaurus-theme-openapi-docs 2.0.2 → 2.0.4
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/theme/ApiExplorer/Body/index.js +8 -1
- package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.d.ts +21 -0
- package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.js +8 -0
- package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +2 -12
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +87 -8
- package/lib/theme/ApiExplorer/CodeSnippets/languages.d.ts +2 -0
- package/lib/theme/ApiExplorer/CodeSnippets/languages.js +32 -0
- package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +14 -0
- package/lib/theme/ApiExplorer/CodeTabs/index.js +7 -0
- package/lib/theme/ApiExplorer/index.js +1 -1
- package/lib/theme/ApiTabs/index.js +11 -3
- package/lib/theme/Markdown/index.js +37 -0
- package/lib/theme/OperationTabs/_OperationTabs.scss +68 -0
- package/lib/theme/OperationTabs/index.js +187 -0
- package/lib/theme/styles.scss +1 -0
- package/package.json +3 -3
- package/src/theme/ApiExplorer/Body/index.tsx +3 -1
- package/src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts +55 -0
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +94 -21
- package/src/theme/ApiExplorer/CodeSnippets/languages.ts +37 -0
- package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +14 -0
- package/src/theme/ApiExplorer/CodeTabs/index.js +7 -0
- package/src/theme/ApiExplorer/index.tsx +1 -1
- package/src/theme/ApiTabs/index.js +11 -3
- package/src/theme/Markdown/index.js +37 -0
- package/src/theme/OperationTabs/_OperationTabs.scss +68 -0
- package/src/theme/OperationTabs/index.js +187 -0
- package/src/theme/styles.scss +1 -0
- package/src/theme-openapi.d.ts +4 -0
- package/lib/theme/ApiExplorer/CodeSnippets/languages.json +0 -1386
- package/src/theme/ApiExplorer/CodeSnippets/languages.json +0 -1386
|
@@ -0,0 +1,187 @@
|
|
|
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, { cloneElement, useEffect, useState, useRef } from "react";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
useScrollPositionBlocker,
|
|
12
|
+
useTabs,
|
|
13
|
+
} from "@docusaurus/theme-common/internal";
|
|
14
|
+
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
15
|
+
import clsx from "clsx";
|
|
16
|
+
|
|
17
|
+
function TabList({ className, block, selectedValue, selectValue, tabValues }) {
|
|
18
|
+
const tabRefs = [];
|
|
19
|
+
const { blockElementScrollPositionUntilNextRender } =
|
|
20
|
+
useScrollPositionBlocker();
|
|
21
|
+
|
|
22
|
+
const handleTabChange = (event) => {
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
const newTab = event.currentTarget;
|
|
25
|
+
const newTabIndex = tabRefs.indexOf(newTab);
|
|
26
|
+
const newTabValue = tabValues[newTabIndex].value;
|
|
27
|
+
// custom
|
|
28
|
+
if (newTabValue !== selectedValue) {
|
|
29
|
+
blockElementScrollPositionUntilNextRender(newTab);
|
|
30
|
+
selectValue(newTabValue);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleKeydown = (event) => {
|
|
35
|
+
let focusElement = null;
|
|
36
|
+
switch (event.key) {
|
|
37
|
+
case "Enter": {
|
|
38
|
+
handleTabChange(event);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "ArrowRight": {
|
|
42
|
+
const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
|
|
43
|
+
focusElement = tabRefs[nextTab] ?? tabRefs[0];
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case "ArrowLeft": {
|
|
47
|
+
const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
|
|
48
|
+
focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1];
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
default:
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
focusElement?.focus();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const tabItemListContainerRef = useRef(null);
|
|
58
|
+
const [showTabArrows, setShowTabArrows] = useState(false);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
62
|
+
for (let entry of entries) {
|
|
63
|
+
if (entry.target.offsetWidth < entry.target.scrollWidth) {
|
|
64
|
+
setShowTabArrows(true);
|
|
65
|
+
} else {
|
|
66
|
+
setShowTabArrows(false);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
resizeObserver.observe(tabItemListContainerRef.current);
|
|
72
|
+
|
|
73
|
+
return () => {
|
|
74
|
+
resizeObserver.disconnect();
|
|
75
|
+
};
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
const handleRightClick = () => {
|
|
79
|
+
tabItemListContainerRef.current.scrollLeft += 90;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const handleLeftClick = () => {
|
|
83
|
+
tabItemListContainerRef.current.scrollLeft -= 90;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="tabs__container">
|
|
88
|
+
<div className="openapi-tabs__operation-container">
|
|
89
|
+
{showTabArrows && (
|
|
90
|
+
<button
|
|
91
|
+
className={clsx("openapi-tabs__arrow", "left")}
|
|
92
|
+
onClick={handleLeftClick}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
95
|
+
<ul
|
|
96
|
+
ref={tabItemListContainerRef}
|
|
97
|
+
role="tablist"
|
|
98
|
+
aria-orientation="horizontal"
|
|
99
|
+
className={clsx(
|
|
100
|
+
"openapi-tabs__operation-list-container",
|
|
101
|
+
"tabs",
|
|
102
|
+
{
|
|
103
|
+
"tabs--block": block,
|
|
104
|
+
},
|
|
105
|
+
className
|
|
106
|
+
)}
|
|
107
|
+
>
|
|
108
|
+
{tabValues.map(({ value, label, attributes }) => {
|
|
109
|
+
return (
|
|
110
|
+
<li
|
|
111
|
+
role="tab"
|
|
112
|
+
tabIndex={selectedValue === value ? 0 : -1}
|
|
113
|
+
aria-selected={selectedValue === value}
|
|
114
|
+
key={value}
|
|
115
|
+
ref={(tabControl) => tabRefs.push(tabControl)}
|
|
116
|
+
onKeyDown={handleKeydown}
|
|
117
|
+
onFocus={handleTabChange}
|
|
118
|
+
onClick={(e) => handleTabChange(e)}
|
|
119
|
+
{...attributes}
|
|
120
|
+
className={clsx(
|
|
121
|
+
"tabs__item",
|
|
122
|
+
"openapi-tabs__operation-item",
|
|
123
|
+
attributes?.className,
|
|
124
|
+
{
|
|
125
|
+
active: selectedValue === value,
|
|
126
|
+
}
|
|
127
|
+
)}
|
|
128
|
+
>
|
|
129
|
+
{label ?? value}
|
|
130
|
+
</li>
|
|
131
|
+
);
|
|
132
|
+
})}
|
|
133
|
+
</ul>
|
|
134
|
+
{showTabArrows && (
|
|
135
|
+
<button
|
|
136
|
+
className={clsx("openapi-tabs__arrow", "right")}
|
|
137
|
+
onClick={handleRightClick}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
function TabContent({ lazy, children, selectedValue }) {
|
|
145
|
+
// eslint-disable-next-line no-param-reassign
|
|
146
|
+
children = Array.isArray(children) ? children : [children];
|
|
147
|
+
if (lazy) {
|
|
148
|
+
const selectedTabItem = children.find(
|
|
149
|
+
(tabItem) => tabItem.props.value === selectedValue
|
|
150
|
+
);
|
|
151
|
+
if (!selectedTabItem) {
|
|
152
|
+
// fail-safe or fail-fast? not sure what's best here
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return cloneElement(selectedTabItem, { className: "margin-top--md" });
|
|
156
|
+
}
|
|
157
|
+
return (
|
|
158
|
+
<div className="margin-top--md">
|
|
159
|
+
{children.map((tabItem, i) =>
|
|
160
|
+
cloneElement(tabItem, {
|
|
161
|
+
key: i,
|
|
162
|
+
hidden: tabItem.props.value !== selectedValue,
|
|
163
|
+
})
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function TabsComponent(props) {
|
|
169
|
+
const tabs = useTabs(props);
|
|
170
|
+
return (
|
|
171
|
+
<div className="tabs-container">
|
|
172
|
+
<TabList {...props} {...tabs} />
|
|
173
|
+
<TabContent {...props} {...tabs} />
|
|
174
|
+
</div>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
export default function OperationTabs(props) {
|
|
178
|
+
const isBrowser = useIsBrowser();
|
|
179
|
+
return (
|
|
180
|
+
<TabsComponent
|
|
181
|
+
// Remount tabs after hydration
|
|
182
|
+
// Temporary fix for https://github.com/facebook/docusaurus/issues/5653
|
|
183
|
+
key={String(isBrowser)}
|
|
184
|
+
{...props}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
}
|
package/lib/theme/styles.scss
CHANGED
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": "2.0.
|
|
4
|
+
"version": "2.0.4",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"clsx": "^1.1.1",
|
|
44
44
|
"copy-text-to-clipboard": "^3.1.0",
|
|
45
45
|
"crypto-js": "^4.1.1",
|
|
46
|
-
"docusaurus-plugin-openapi-docs": "^2.0.
|
|
46
|
+
"docusaurus-plugin-openapi-docs": "^2.0.4",
|
|
47
47
|
"docusaurus-plugin-sass": "^0.2.3",
|
|
48
48
|
"file-saver": "^2.0.5",
|
|
49
49
|
"lodash": "^4.17.20",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"engines": {
|
|
69
69
|
"node": ">=14"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "71012fa9a8e21d7d83beaf6368b93381298a3e2e"
|
|
72
72
|
}
|
|
@@ -14,6 +14,7 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
|
14
14
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
15
15
|
import LiveApp from "@theme/ApiExplorer/LiveEditor";
|
|
16
16
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
17
|
+
import Markdown from "@theme/Markdown";
|
|
17
18
|
import SchemaTabs from "@theme/SchemaTabs";
|
|
18
19
|
import TabItem from "@theme/TabItem";
|
|
19
20
|
import { RequestBodyObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
@@ -303,6 +304,7 @@ function Body({
|
|
|
303
304
|
</TabItem>
|
|
304
305
|
{/* @ts-ignore */}
|
|
305
306
|
<TabItem label="Example" value="example">
|
|
307
|
+
{example.summary && <Markdown children={example.summary} />}
|
|
306
308
|
{exampleBody && (
|
|
307
309
|
<LiveApp
|
|
308
310
|
action={dispatch}
|
|
@@ -340,7 +342,7 @@ function Body({
|
|
|
340
342
|
value={example.label}
|
|
341
343
|
key={example.label}
|
|
342
344
|
>
|
|
343
|
-
{example.summary && <
|
|
345
|
+
{example.summary && <Markdown children={example.summary} />}
|
|
344
346
|
{example.body && (
|
|
345
347
|
<LiveApp action={dispatch} language={language}>
|
|
346
348
|
{example.body}
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
// https://github.com/github-linguist/linguist/blob/master/lib/linguist/popular.yml
|
|
9
|
+
export type CodeSampleLanguage =
|
|
10
|
+
| "C"
|
|
11
|
+
| "C#"
|
|
12
|
+
| "C++"
|
|
13
|
+
| "CoffeeScript"
|
|
14
|
+
| "CSS"
|
|
15
|
+
| "Dart"
|
|
16
|
+
| "DM"
|
|
17
|
+
| "Elixir"
|
|
18
|
+
| "Go"
|
|
19
|
+
| "Groovy"
|
|
20
|
+
| "HTML"
|
|
21
|
+
| "Java"
|
|
22
|
+
| "JavaScript"
|
|
23
|
+
| "Kotlin"
|
|
24
|
+
| "Objective-C"
|
|
25
|
+
| "Perl"
|
|
26
|
+
| "PHP"
|
|
27
|
+
| "PowerShell"
|
|
28
|
+
| "Python"
|
|
29
|
+
| "Ruby"
|
|
30
|
+
| "Rust"
|
|
31
|
+
| "Scala"
|
|
32
|
+
| "Shell"
|
|
33
|
+
| "Swift"
|
|
34
|
+
| "TypeScript";
|
|
35
|
+
|
|
36
|
+
export interface Language {
|
|
37
|
+
highlight: string;
|
|
38
|
+
language: string;
|
|
39
|
+
codeSampleLanguage: CodeSampleLanguage;
|
|
40
|
+
logoClass: string;
|
|
41
|
+
variant: string;
|
|
42
|
+
variants: string[];
|
|
43
|
+
options?: { [key: string]: boolean };
|
|
44
|
+
sample?: string;
|
|
45
|
+
samples?: string[];
|
|
46
|
+
samplesSources?: string[];
|
|
47
|
+
samplesLabels?: string[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples
|
|
51
|
+
export interface CodeSample {
|
|
52
|
+
source: string;
|
|
53
|
+
lang: CodeSampleLanguage;
|
|
54
|
+
label?: string;
|
|
55
|
+
}
|
|
@@ -16,20 +16,14 @@ import CodeTabs from "@theme/ApiExplorer/CodeTabs";
|
|
|
16
16
|
import { useTypedSelector } from "@theme/ApiItem/hooks";
|
|
17
17
|
import merge from "lodash/merge";
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
language: string;
|
|
22
|
-
logoClass: string;
|
|
23
|
-
variant: string;
|
|
24
|
-
variants: string[];
|
|
25
|
-
options: { [key: string]: boolean };
|
|
26
|
-
source?: string;
|
|
27
|
-
}
|
|
19
|
+
import { CodeSample, Language } from "./code-snippets-types";
|
|
20
|
+
import { mergeCodeSampleLanguage } from "./languages";
|
|
28
21
|
|
|
29
22
|
export const languageSet: Language[] = [
|
|
30
23
|
{
|
|
31
24
|
highlight: "bash",
|
|
32
25
|
language: "curl",
|
|
26
|
+
codeSampleLanguage: "Shell",
|
|
33
27
|
logoClass: "bash",
|
|
34
28
|
options: {
|
|
35
29
|
longFormat: false,
|
|
@@ -42,6 +36,7 @@ export const languageSet: Language[] = [
|
|
|
42
36
|
{
|
|
43
37
|
highlight: "python",
|
|
44
38
|
language: "python",
|
|
39
|
+
codeSampleLanguage: "Python",
|
|
45
40
|
logoClass: "python",
|
|
46
41
|
options: {
|
|
47
42
|
followRedirect: true,
|
|
@@ -53,6 +48,7 @@ export const languageSet: Language[] = [
|
|
|
53
48
|
{
|
|
54
49
|
highlight: "go",
|
|
55
50
|
language: "go",
|
|
51
|
+
codeSampleLanguage: "Go",
|
|
56
52
|
logoClass: "go",
|
|
57
53
|
options: {
|
|
58
54
|
followRedirect: true,
|
|
@@ -64,6 +60,7 @@ export const languageSet: Language[] = [
|
|
|
64
60
|
{
|
|
65
61
|
highlight: "javascript",
|
|
66
62
|
language: "nodejs",
|
|
63
|
+
codeSampleLanguage: "JavaScript",
|
|
67
64
|
logoClass: "nodejs",
|
|
68
65
|
options: {
|
|
69
66
|
ES6_enabled: true,
|
|
@@ -71,11 +68,12 @@ export const languageSet: Language[] = [
|
|
|
71
68
|
trimRequestBody: true,
|
|
72
69
|
},
|
|
73
70
|
variant: "axios",
|
|
74
|
-
variants: ["axios", "native"
|
|
71
|
+
variants: ["axios", "native"],
|
|
75
72
|
},
|
|
76
73
|
{
|
|
77
74
|
highlight: "ruby",
|
|
78
75
|
language: "ruby",
|
|
76
|
+
codeSampleLanguage: "Ruby",
|
|
79
77
|
logoClass: "ruby",
|
|
80
78
|
options: {
|
|
81
79
|
followRedirect: true,
|
|
@@ -87,6 +85,7 @@ export const languageSet: Language[] = [
|
|
|
87
85
|
{
|
|
88
86
|
highlight: "csharp",
|
|
89
87
|
language: "csharp",
|
|
88
|
+
codeSampleLanguage: "C#",
|
|
90
89
|
logoClass: "csharp",
|
|
91
90
|
options: {
|
|
92
91
|
followRedirect: true,
|
|
@@ -98,6 +97,7 @@ export const languageSet: Language[] = [
|
|
|
98
97
|
{
|
|
99
98
|
highlight: "php",
|
|
100
99
|
language: "php",
|
|
100
|
+
codeSampleLanguage: "PHP",
|
|
101
101
|
logoClass: "php",
|
|
102
102
|
options: {
|
|
103
103
|
followRedirect: true,
|
|
@@ -109,6 +109,7 @@ export const languageSet: Language[] = [
|
|
|
109
109
|
{
|
|
110
110
|
highlight: "java",
|
|
111
111
|
language: "java",
|
|
112
|
+
codeSampleLanguage: "Java",
|
|
112
113
|
logoClass: "java",
|
|
113
114
|
options: {
|
|
114
115
|
followRedirect: true,
|
|
@@ -120,6 +121,7 @@ export const languageSet: Language[] = [
|
|
|
120
121
|
{
|
|
121
122
|
highlight: "powershell",
|
|
122
123
|
language: "powershell",
|
|
124
|
+
codeSampleLanguage: "PowerShell",
|
|
123
125
|
logoClass: "powershell",
|
|
124
126
|
options: {
|
|
125
127
|
followRedirect: true,
|
|
@@ -132,10 +134,10 @@ export const languageSet: Language[] = [
|
|
|
132
134
|
|
|
133
135
|
export interface Props {
|
|
134
136
|
postman: sdk.Request;
|
|
135
|
-
codeSamples:
|
|
137
|
+
codeSamples: CodeSample[];
|
|
136
138
|
}
|
|
137
139
|
|
|
138
|
-
function CodeTab({ children, hidden, className
|
|
140
|
+
function CodeTab({ children, hidden, className }: any): JSX.Element {
|
|
139
141
|
return (
|
|
140
142
|
<div role="tabpanel" className={className} {...{ hidden }}>
|
|
141
143
|
{children}
|
|
@@ -165,7 +167,6 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
165
167
|
const langs = [
|
|
166
168
|
...((siteConfig?.themeConfig?.languageTabs as Language[] | undefined) ??
|
|
167
169
|
languageSet),
|
|
168
|
-
...codeSamples,
|
|
169
170
|
];
|
|
170
171
|
|
|
171
172
|
// Filter languageSet by user-defined langs
|
|
@@ -176,14 +177,18 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
176
177
|
});
|
|
177
178
|
|
|
178
179
|
// Merge user-defined langs into languageSet
|
|
179
|
-
const mergedLangs =
|
|
180
|
+
const mergedLangs = mergeCodeSampleLanguage(
|
|
181
|
+
merge(filteredLanguageSet, langs),
|
|
182
|
+
codeSamples
|
|
183
|
+
);
|
|
180
184
|
|
|
181
185
|
// Read defaultLang from localStorage
|
|
182
186
|
const defaultLang: Language[] = mergedLangs.filter(
|
|
183
187
|
(lang) =>
|
|
184
188
|
lang.language === localStorage.getItem("docusaurus.tab.code-samples")
|
|
185
189
|
);
|
|
186
|
-
const [selectedVariant, setSelectedVariant] = useState();
|
|
190
|
+
const [selectedVariant, setSelectedVariant] = useState<string | undefined>();
|
|
191
|
+
const [selectedSample, setSelectedSample] = useState<string | undefined>();
|
|
187
192
|
const [language, setLanguage] = useState(() => {
|
|
188
193
|
// Return first index if only 1 user-defined language exists
|
|
189
194
|
if (mergedLangs.length === 1) {
|
|
@@ -192,9 +197,23 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
192
197
|
// Fall back to language in localStorage or first user-defined language
|
|
193
198
|
return defaultLang[0] ?? mergedLangs[0];
|
|
194
199
|
});
|
|
195
|
-
const [codeText, setCodeText] = useState("");
|
|
200
|
+
const [codeText, setCodeText] = useState<string>("");
|
|
201
|
+
const [codeSampleCodeText, setCodeSampleCodeText] = useState<string>("");
|
|
196
202
|
|
|
197
203
|
useEffect(() => {
|
|
204
|
+
// initial active language is custom code sample
|
|
205
|
+
if (
|
|
206
|
+
language &&
|
|
207
|
+
language.sample &&
|
|
208
|
+
language.samples &&
|
|
209
|
+
language.samplesSources
|
|
210
|
+
) {
|
|
211
|
+
const sampleIndex = language.samples.findIndex(
|
|
212
|
+
(smp) => smp === language.sample
|
|
213
|
+
);
|
|
214
|
+
setCodeSampleCodeText(language.samplesSources[sampleIndex]);
|
|
215
|
+
}
|
|
216
|
+
|
|
198
217
|
if (language && !!language.options) {
|
|
199
218
|
const postmanRequest = buildPostmanRequest(postman, {
|
|
200
219
|
queryParams,
|
|
@@ -219,8 +238,6 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
219
238
|
setCodeText(snippet);
|
|
220
239
|
}
|
|
221
240
|
);
|
|
222
|
-
} else if (language && !!language.source) {
|
|
223
|
-
setCodeText(language.source);
|
|
224
241
|
} else if (language && !language.options) {
|
|
225
242
|
const langSource = mergedLangs.filter(
|
|
226
243
|
(lang) => lang.language === language.language
|
|
@@ -271,8 +288,8 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
271
288
|
auth,
|
|
272
289
|
mergedLangs,
|
|
273
290
|
]);
|
|
274
|
-
|
|
275
|
-
useEffect(()
|
|
291
|
+
// no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
|
|
292
|
+
useEffect(function onSelectedVariantUpdate() {
|
|
276
293
|
if (selectedVariant && selectedVariant !== language.variant) {
|
|
277
294
|
const postmanRequest = buildPostmanRequest(postman, {
|
|
278
295
|
queryParams,
|
|
@@ -300,6 +317,22 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
300
317
|
}
|
|
301
318
|
});
|
|
302
319
|
|
|
320
|
+
// no dependencies was intentionlly set for this particular hook. it's safe as long as if conditions are set
|
|
321
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
322
|
+
useEffect(function onSelectedSampleUpdate() {
|
|
323
|
+
if (
|
|
324
|
+
language.samples &&
|
|
325
|
+
language.samplesSources &&
|
|
326
|
+
selectedSample &&
|
|
327
|
+
selectedSample !== language.sample
|
|
328
|
+
) {
|
|
329
|
+
const sampleIndex = language.samples.findIndex(
|
|
330
|
+
(smp) => smp === selectedSample
|
|
331
|
+
);
|
|
332
|
+
setCodeSampleCodeText(language.samplesSources[sampleIndex]);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
303
336
|
if (language === undefined) {
|
|
304
337
|
return null;
|
|
305
338
|
}
|
|
@@ -324,6 +357,46 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
324
357
|
className: `openapi-tabs__code-item--${lang.logoClass}`,
|
|
325
358
|
}}
|
|
326
359
|
>
|
|
360
|
+
{lang.samples && (
|
|
361
|
+
<CodeTabs
|
|
362
|
+
className="openapi-tabs__code-container-inner"
|
|
363
|
+
action={{
|
|
364
|
+
setLanguage: setLanguage,
|
|
365
|
+
setSelectedSample: setSelectedSample,
|
|
366
|
+
}}
|
|
367
|
+
includeSample={true}
|
|
368
|
+
currentLanguage={lang.language}
|
|
369
|
+
defaultValue={selectedSample}
|
|
370
|
+
lazy
|
|
371
|
+
>
|
|
372
|
+
{lang.samples.map((sample, index) => {
|
|
373
|
+
return (
|
|
374
|
+
<CodeTab
|
|
375
|
+
value={sample}
|
|
376
|
+
label={
|
|
377
|
+
lang.samplesLabels
|
|
378
|
+
? lang.samplesLabels[index]
|
|
379
|
+
: sample
|
|
380
|
+
}
|
|
381
|
+
key={`${lang.language}-${lang.sample}`}
|
|
382
|
+
attributes={{
|
|
383
|
+
className: `openapi-tabs__code-item--sample`,
|
|
384
|
+
}}
|
|
385
|
+
>
|
|
386
|
+
{/* @ts-ignore */}
|
|
387
|
+
<ApiCodeBlock
|
|
388
|
+
language={lang.highlight}
|
|
389
|
+
className="openapi-explorer__code-block"
|
|
390
|
+
showLineNumbers={true}
|
|
391
|
+
>
|
|
392
|
+
{codeSampleCodeText}
|
|
393
|
+
</ApiCodeBlock>
|
|
394
|
+
</CodeTab>
|
|
395
|
+
);
|
|
396
|
+
})}
|
|
397
|
+
</CodeTabs>
|
|
398
|
+
)}
|
|
399
|
+
|
|
327
400
|
<CodeTabs
|
|
328
401
|
className="openapi-tabs__code-container-inner"
|
|
329
402
|
action={{
|
|
@@ -335,7 +408,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
|
|
|
335
408
|
defaultValue={selectedVariant}
|
|
336
409
|
lazy
|
|
337
410
|
>
|
|
338
|
-
{lang.variants.map((variant) => {
|
|
411
|
+
{lang.variants.map((variant, index) => {
|
|
339
412
|
return (
|
|
340
413
|
<CodeTab
|
|
341
414
|
value={variant.toLowerCase()}
|
|
@@ -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 { CodeSample, Language } from "./code-snippets-types";
|
|
9
|
+
|
|
10
|
+
export function mergeCodeSampleLanguage(
|
|
11
|
+
languages: Language[],
|
|
12
|
+
codeSamples: CodeSample[]
|
|
13
|
+
): Language[] {
|
|
14
|
+
return languages.map((language) => {
|
|
15
|
+
const languageCodeSamples = codeSamples.filter(
|
|
16
|
+
({ lang }) => lang === language.codeSampleLanguage
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (languageCodeSamples.length) {
|
|
20
|
+
const samples = languageCodeSamples.map(({ lang }) => lang);
|
|
21
|
+
const samplesLabels = languageCodeSamples.map(
|
|
22
|
+
({ label, lang }) => label || lang
|
|
23
|
+
);
|
|
24
|
+
const samplesSources = languageCodeSamples.map(({ source }) => source);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
...language,
|
|
28
|
+
sample: samples[0],
|
|
29
|
+
samples,
|
|
30
|
+
samplesSources,
|
|
31
|
+
samplesLabels,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return language;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -94,6 +94,20 @@ body[class="ReactModal__Body--open"] {
|
|
|
94
94
|
padding-right: 0.5rem !important;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
.openapi-tabs__code-item--sample {
|
|
98
|
+
color: var(--ifm-color-secondary);
|
|
99
|
+
|
|
100
|
+
&.active {
|
|
101
|
+
border-color: var(--ifm-toc-border-color);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.openapi-tabs__code-item--sample > span {
|
|
106
|
+
padding-top: unset !important;
|
|
107
|
+
padding-left: 0.5rem !important;
|
|
108
|
+
padding-right: 0.5rem !important;
|
|
109
|
+
}
|
|
110
|
+
|
|
97
111
|
.openapi-tabs__code-item--python {
|
|
98
112
|
color: var(--ifm-color-success);
|
|
99
113
|
|
|
@@ -19,6 +19,7 @@ function TabList({
|
|
|
19
19
|
action,
|
|
20
20
|
currentLanguage,
|
|
21
21
|
includeVariant,
|
|
22
|
+
includeSample,
|
|
22
23
|
className,
|
|
23
24
|
block,
|
|
24
25
|
selectedValue,
|
|
@@ -53,6 +54,12 @@ function TabList({
|
|
|
53
54
|
)[0];
|
|
54
55
|
action.setSelectedVariant(newLanguage.variant.toLowerCase());
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
if (currentLanguage && includeSample) {
|
|
59
|
+
newLanguage.sample = newTabValue;
|
|
60
|
+
action.setSelectedSample(newTabValue.toLowerCase());
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
action.setLanguage(newLanguage);
|
|
57
64
|
}
|
|
58
65
|
};
|
|
@@ -15,7 +15,15 @@ import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
|
15
15
|
import Heading from "@theme/Heading";
|
|
16
16
|
import clsx from "clsx";
|
|
17
17
|
|
|
18
|
-
function TabList({
|
|
18
|
+
function TabList({
|
|
19
|
+
className,
|
|
20
|
+
block,
|
|
21
|
+
selectedValue,
|
|
22
|
+
selectValue,
|
|
23
|
+
tabValues,
|
|
24
|
+
label = "Responses",
|
|
25
|
+
id = "responses",
|
|
26
|
+
}) {
|
|
19
27
|
const tabRefs = [];
|
|
20
28
|
const { blockElementScrollPositionUntilNextRender } =
|
|
21
29
|
useScrollPositionBlocker();
|
|
@@ -84,8 +92,8 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
|
|
|
84
92
|
|
|
85
93
|
return (
|
|
86
94
|
<div className="openapi-tabs__response-header-section">
|
|
87
|
-
<Heading as="h2" id=
|
|
88
|
-
|
|
95
|
+
<Heading as="h2" id={id} className="openapi-tabs__response-header">
|
|
96
|
+
{label}
|
|
89
97
|
</Heading>
|
|
90
98
|
<div className="openapi-tabs__response-container">
|
|
91
99
|
{showTabArrows && (
|