docusaurus-theme-openapi-docs 0.0.0-688 → 0.0.0-690
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/ApiTabs/index.js +11 -3
- 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/ApiTabs/index.js +11 -3
- package/src/theme/OperationTabs/_OperationTabs.scss +68 -0
- package/src/theme/OperationTabs/index.js +187 -0
- package/src/theme/styles.scss +1 -0
|
@@ -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 && (
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
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
|
+
.openapi-tabs__operation-container {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
margin-top: 1rem;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.openapi-tabs__operation-item {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
padding: 0.35rem 0.7rem;
|
|
20
|
+
border: 1px solid transparent;
|
|
21
|
+
margin-top: 0 !important;
|
|
22
|
+
margin-right: 0.5rem;
|
|
23
|
+
font-weight: var(--ifm-font-weight-bold);
|
|
24
|
+
font-size: 12px;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
transition: 300ms;
|
|
27
|
+
|
|
28
|
+
&:hover {
|
|
29
|
+
background-color: transparent;
|
|
30
|
+
border: 1px solid var(--ifm-toc-border-color);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.active {
|
|
34
|
+
border: 1px solid var(--ifm-tabs-color-active-border);
|
|
35
|
+
color: var(--ifm-tabs-color-active);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:last-child {
|
|
39
|
+
margin-right: 0 !important;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.openapi-tabs__operation-list-container {
|
|
44
|
+
overflow-y: hidden;
|
|
45
|
+
overflow-x: scroll;
|
|
46
|
+
scroll-behavior: smooth;
|
|
47
|
+
|
|
48
|
+
&::-webkit-scrollbar {
|
|
49
|
+
display: none;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.openapi-tabs__operation-schema-container {
|
|
54
|
+
max-width: 600px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@media screen and (max-width: 500px) {
|
|
58
|
+
.operationTabsTopSection {
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
align-items: flex-start;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.operationTabsContainer {
|
|
64
|
+
width: 100%;
|
|
65
|
+
margin-top: var(--ifm-spacing-vertical);
|
|
66
|
+
padding: 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -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": "0.0.0-
|
|
4
|
+
"version": "0.0.0-690",
|
|
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": "
|
|
46
|
+
"docusaurus-plugin-openapi-docs": "0.0.0-690",
|
|
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": "68d6bc5c3e39aba589cdebe0189820179be60c18"
|
|
72
72
|
}
|
|
@@ -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 && (
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
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
|
+
.openapi-tabs__operation-container {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
margin-top: 1rem;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.openapi-tabs__operation-item {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
padding: 0.35rem 0.7rem;
|
|
20
|
+
border: 1px solid transparent;
|
|
21
|
+
margin-top: 0 !important;
|
|
22
|
+
margin-right: 0.5rem;
|
|
23
|
+
font-weight: var(--ifm-font-weight-bold);
|
|
24
|
+
font-size: 12px;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
transition: 300ms;
|
|
27
|
+
|
|
28
|
+
&:hover {
|
|
29
|
+
background-color: transparent;
|
|
30
|
+
border: 1px solid var(--ifm-toc-border-color);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.active {
|
|
34
|
+
border: 1px solid var(--ifm-tabs-color-active-border);
|
|
35
|
+
color: var(--ifm-tabs-color-active);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:last-child {
|
|
39
|
+
margin-right: 0 !important;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.openapi-tabs__operation-list-container {
|
|
44
|
+
overflow-y: hidden;
|
|
45
|
+
overflow-x: scroll;
|
|
46
|
+
scroll-behavior: smooth;
|
|
47
|
+
|
|
48
|
+
&::-webkit-scrollbar {
|
|
49
|
+
display: none;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.openapi-tabs__operation-schema-container {
|
|
54
|
+
max-width: 600px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@media screen and (max-width: 500px) {
|
|
58
|
+
.operationTabsTopSection {
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
align-items: flex-start;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.operationTabsContainer {
|
|
64
|
+
width: 100%;
|
|
65
|
+
margin-top: var(--ifm-spacing-vertical);
|
|
66
|
+
padding: 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -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/src/theme/styles.scss
CHANGED