docusaurus-theme-openapi-docs 3.0.0-beta.1 → 3.0.0-beta.10

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 (142) hide show
  1. package/lib/markdown/utils.d.ts +3 -2
  2. package/lib/markdown/utils.js +1 -1
  3. package/lib/markdown/utils.test.d.ts +1 -0
  4. package/lib/markdown/utils.test.js +43 -0
  5. package/lib/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/index.d.ts +13 -0
  6. package/lib/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/index.js +199 -124
  7. package/lib/theme/ApiExplorer/Accept/index.d.ts +2 -2
  8. package/lib/theme/ApiExplorer/ApiCodeBlock/Container/index.d.ts +4 -0
  9. package/lib/theme/ApiExplorer/ApiCodeBlock/Container/index.js +25 -19
  10. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/Element.d.ts +4 -0
  11. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/Element.js +27 -16
  12. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.d.ts +4 -0
  13. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.js +115 -96
  14. package/lib/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.d.ts +3 -0
  15. package/lib/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.js +115 -54
  16. package/lib/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.d.ts +6 -0
  17. package/lib/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.js +41 -30
  18. package/lib/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.d.ts +14 -0
  19. package/lib/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.js +200 -120
  20. package/lib/theme/ApiExplorer/ApiCodeBlock/Line/index.d.ts +3 -0
  21. package/lib/theme/ApiExplorer/ApiCodeBlock/Line/index.js +36 -24
  22. package/lib/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.d.ts +7 -0
  23. package/lib/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.js +35 -28
  24. package/lib/theme/ApiExplorer/ApiCodeBlock/index.d.ts +3 -0
  25. package/lib/theme/ApiExplorer/ApiCodeBlock/index.js +72 -14
  26. package/lib/theme/ApiExplorer/Authorization/index.d.ts +2 -2
  27. package/lib/theme/ApiExplorer/Authorization/slice.d.ts +1 -1
  28. package/lib/theme/ApiExplorer/Body/index.d.ts +2 -2
  29. package/lib/theme/ApiExplorer/Body/index.js +8 -1
  30. package/lib/theme/ApiExplorer/Body/slice.d.ts +3 -3
  31. package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.d.ts +21 -0
  32. package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.js +8 -0
  33. package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +4 -14
  34. package/lib/theme/ApiExplorer/CodeSnippets/index.js +86 -8
  35. package/lib/theme/ApiExplorer/CodeSnippets/languages.d.ts +3 -0
  36. package/lib/theme/ApiExplorer/CodeSnippets/languages.js +48 -0
  37. package/lib/theme/ApiExplorer/CodeSnippets/languages.json +0 -96
  38. package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +18 -2
  39. package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +15 -0
  40. package/lib/theme/ApiExplorer/CodeTabs/index.js +131 -76
  41. package/lib/theme/ApiExplorer/ContentType/index.d.ts +2 -2
  42. package/lib/theme/ApiExplorer/Export/index.d.ts +2 -2
  43. package/lib/theme/ApiExplorer/FloatingButton/_FloatingButton.scss +3 -1
  44. package/lib/theme/ApiExplorer/FloatingButton/index.d.ts +1 -1
  45. package/lib/theme/ApiExplorer/FormFileUpload/index.d.ts +2 -2
  46. package/lib/theme/ApiExplorer/FormItem/index.d.ts +1 -1
  47. package/lib/theme/ApiExplorer/FormMultiSelect/index.d.ts +1 -1
  48. package/lib/theme/ApiExplorer/FormSelect/index.d.ts +1 -1
  49. package/lib/theme/ApiExplorer/FormTextInput/index.d.ts +1 -1
  50. package/lib/theme/ApiExplorer/MethodEndpoint/index.d.ts +2 -2
  51. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.d.ts +2 -2
  52. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.d.ts +2 -2
  53. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.d.ts +2 -2
  54. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +4 -4
  55. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.d.ts +2 -2
  56. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.d.ts +2 -2
  57. package/lib/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +2 -1
  58. package/lib/theme/ApiExplorer/ParamOptions/index.d.ts +2 -2
  59. package/lib/theme/ApiExplorer/ParamOptions/slice.d.ts +1 -1
  60. package/lib/theme/ApiExplorer/Request/_Request.scss +4 -2
  61. package/lib/theme/ApiExplorer/Request/index.d.ts +2 -2
  62. package/lib/theme/ApiExplorer/Request/makeRequest.js +50 -1
  63. package/lib/theme/ApiExplorer/Response/_Response.scss +4 -2
  64. package/lib/theme/ApiExplorer/Response/index.d.ts +2 -2
  65. package/lib/theme/ApiExplorer/Response/index.js +19 -19
  66. package/lib/theme/ApiExplorer/SecuritySchemes/index.d.ts +2 -2
  67. package/lib/theme/ApiExplorer/Server/index.d.ts +2 -2
  68. package/lib/theme/ApiExplorer/buildPostmanRequest.d.ts +1 -1
  69. package/lib/theme/ApiExplorer/index.d.ts +2 -2
  70. package/lib/theme/ApiExplorer/index.js +1 -1
  71. package/lib/theme/ApiExplorer/storage-utils.d.ts +1 -1
  72. package/lib/theme/ApiItem/index.js +28 -3
  73. package/lib/theme/ApiItem/store.d.ts +6 -6
  74. package/lib/theme/ApiLogo/index.d.ts +2 -2
  75. package/lib/theme/ApiTabs/_ApiTabs.scss +3 -1
  76. package/lib/theme/ApiTabs/index.d.ts +7 -0
  77. package/lib/theme/ApiTabs/index.js +167 -103
  78. package/lib/theme/DiscriminatorTabs/index.d.ts +3 -0
  79. package/lib/theme/DiscriminatorTabs/index.js +152 -98
  80. package/lib/theme/Markdown/index.js +37 -0
  81. package/lib/theme/MimeTabs/index.d.ts +6 -0
  82. package/lib/theme/MimeTabs/index.js +169 -118
  83. package/lib/theme/OperationTabs/_OperationTabs.scss +71 -0
  84. package/lib/theme/OperationTabs/index.d.ts +3 -0
  85. package/lib/theme/OperationTabs/index.js +234 -0
  86. package/lib/theme/ParamsItem/index.d.ts +23 -0
  87. package/lib/theme/ParamsItem/index.js +170 -111
  88. package/lib/theme/ResponseSamples/index.d.ts +8 -0
  89. package/lib/theme/ResponseSamples/index.js +18 -13
  90. package/lib/theme/SchemaItem/index.d.ts +12 -0
  91. package/lib/theme/SchemaItem/index.js +121 -89
  92. package/lib/theme/SchemaTabs/_SchemaTabs.scss +0 -4
  93. package/lib/theme/SchemaTabs/index.d.ts +3 -0
  94. package/lib/theme/SchemaTabs/index.js +148 -95
  95. package/lib/theme/styles.scss +5 -0
  96. package/lib/types.d.ts +4 -4
  97. package/package.json +8 -7
  98. package/src/markdown/utils.test.ts +49 -0
  99. package/src/markdown/utils.ts +5 -3
  100. package/src/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/{index.js → index.tsx} +21 -8
  101. package/src/theme/ApiExplorer/ApiCodeBlock/Container/{index.js → index.tsx} +6 -3
  102. package/src/theme/ApiExplorer/ApiCodeBlock/Content/{Element.js → Element.tsx} +5 -1
  103. package/src/theme/ApiExplorer/ApiCodeBlock/Content/{String.js → String.tsx} +4 -4
  104. package/src/theme/ApiExplorer/ApiCodeBlock/CopyButton/{index.js → index.tsx} +8 -3
  105. package/src/theme/ApiExplorer/ApiCodeBlock/ExitButton/{index.js → index.tsx} +9 -1
  106. package/src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/{index.js → index.tsx} +12 -2
  107. package/src/theme/ApiExplorer/ApiCodeBlock/Line/{index.js → index.tsx} +2 -1
  108. package/src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/{index.js → index.tsx} +11 -1
  109. package/src/theme/ApiExplorer/ApiCodeBlock/{index.js → index.tsx} +10 -5
  110. package/src/theme/ApiExplorer/Body/index.tsx +3 -1
  111. package/src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts +55 -0
  112. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +94 -21
  113. package/src/theme/ApiExplorer/CodeSnippets/languages.json +0 -96
  114. package/src/theme/ApiExplorer/CodeSnippets/languages.ts +53 -0
  115. package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +18 -2
  116. package/src/theme/ApiExplorer/CodeTabs/{index.js → index.tsx} +64 -25
  117. package/src/theme/ApiExplorer/FloatingButton/_FloatingButton.scss +3 -1
  118. package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +4 -4
  119. package/src/theme/ApiExplorer/ParamOptions/_ParamOptions.scss +2 -1
  120. package/src/theme/ApiExplorer/Request/_Request.scss +4 -2
  121. package/src/theme/ApiExplorer/Request/makeRequest.ts +59 -4
  122. package/src/theme/ApiExplorer/Response/_Response.scss +4 -2
  123. package/src/theme/ApiExplorer/Response/index.tsx +2 -2
  124. package/src/theme/ApiExplorer/index.tsx +1 -1
  125. package/src/theme/ApiItem/index.tsx +22 -3
  126. package/src/theme/ApiLogo/index.tsx +1 -1
  127. package/src/theme/ApiTabs/_ApiTabs.scss +3 -1
  128. package/src/theme/ApiTabs/{index.js → index.tsx} +75 -31
  129. package/src/theme/DiscriminatorTabs/{index.js → index.tsx} +63 -28
  130. package/src/theme/Markdown/index.js +37 -0
  131. package/src/theme/MimeTabs/{index.js → index.tsx} +64 -30
  132. package/src/theme/OperationTabs/_OperationTabs.scss +71 -0
  133. package/src/theme/OperationTabs/index.tsx +218 -0
  134. package/src/theme/ParamsItem/{index.js → index.tsx} +48 -17
  135. package/src/theme/ResponseSamples/{index.js → index.tsx} +10 -1
  136. package/src/theme/SchemaItem/{index.js → index.tsx} +24 -18
  137. package/src/theme/SchemaTabs/_SchemaTabs.scss +0 -4
  138. package/src/theme/SchemaTabs/{index.js → index.tsx} +62 -29
  139. package/src/theme/styles.scss +5 -0
  140. package/src/theme-classic.d.ts +69 -2
  141. package/src/theme-openapi.d.ts +6 -0
  142. package/tsconfig.json +4 -1
@@ -5,31 +5,55 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import React, { cloneElement, useRef, useEffect, useState } from "react";
8
+ import React, {
9
+ cloneElement,
10
+ useRef,
11
+ useEffect,
12
+ useState,
13
+ ReactElement,
14
+ } from "react";
9
15
 
10
16
  import {
17
+ sanitizeTabsChildren,
18
+ TabProps,
11
19
  useScrollPositionBlocker,
12
20
  useTabs,
13
21
  } from "@docusaurus/theme-common/internal";
22
+ import { TabItemProps } from "@docusaurus/theme-common/lib/utils/tabsUtils";
14
23
  import useIsBrowser from "@docusaurus/useIsBrowser";
15
24
  import clsx from "clsx";
16
25
  import flatten from "lodash/flatten";
17
26
 
18
- function TabList({ className, block, selectedValue, selectValue, tabValues }) {
19
- const tabRefs = [];
27
+ function TabList({
28
+ className,
29
+ block,
30
+ selectedValue,
31
+ selectValue,
32
+ tabValues,
33
+ }: TabProps & ReturnType<typeof useTabs>) {
34
+ const tabRefs: (HTMLLIElement | null)[] = [];
20
35
  const { blockElementScrollPositionUntilNextRender } =
21
36
  useScrollPositionBlocker();
22
- const handleTabChange = (event) => {
37
+
38
+ const handleTabChange = (
39
+ event:
40
+ | React.FocusEvent<HTMLLIElement>
41
+ | React.MouseEvent<HTMLLIElement>
42
+ | React.KeyboardEvent<HTMLLIElement>
43
+ ) => {
23
44
  const newTab = event.currentTarget;
24
45
  const newTabIndex = tabRefs.indexOf(newTab);
25
- const newTabValue = tabValues[newTabIndex].value;
46
+ const newTabValue = tabValues[newTabIndex]!.value;
47
+
26
48
  if (newTabValue !== selectedValue) {
27
49
  blockElementScrollPositionUntilNextRender(newTab);
28
50
  selectValue(newTabValue);
29
51
  }
30
52
  };
31
- const handleKeydown = (event) => {
53
+
54
+ const handleKeydown = (event: React.KeyboardEvent<HTMLLIElement>) => {
32
55
  let focusElement = null;
56
+
33
57
  switch (event.key) {
34
58
  case "Enter": {
35
59
  handleTabChange(event);
@@ -37,35 +61,38 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
37
61
  }
38
62
  case "ArrowRight": {
39
63
  const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
40
- focusElement = tabRefs[nextTab] ?? tabRefs[0];
64
+ focusElement = tabRefs[nextTab] ?? tabRefs[0]!;
41
65
  break;
42
66
  }
43
67
  case "ArrowLeft": {
44
68
  const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
45
- focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1];
69
+ focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!;
46
70
  break;
47
71
  }
48
72
  default:
49
73
  break;
50
74
  }
75
+
51
76
  focusElement?.focus();
52
77
  };
53
78
 
54
- const tabItemListContainerRef = useRef(null);
55
- const [showTabArrows, setShowTabArrows] = useState(false);
79
+ const tabItemListContainerRef = useRef<HTMLUListElement>(null);
80
+ const [showTabArrows, setShowTabArrows] = useState<boolean>(false);
56
81
 
57
82
  useEffect(() => {
58
83
  const resizeObserver = new ResizeObserver((entries) => {
59
84
  for (let entry of entries) {
60
- if (entry.target.offsetWidth < entry.target.scrollWidth) {
61
- setShowTabArrows(true);
62
- } else {
63
- setShowTabArrows(false);
64
- }
85
+ requestAnimationFrame(() => {
86
+ if (entry.target.clientWidth < entry.target.scrollWidth) {
87
+ setShowTabArrows(true);
88
+ } else {
89
+ setShowTabArrows(false);
90
+ }
91
+ });
65
92
  }
66
93
  });
67
94
 
68
- resizeObserver.observe(tabItemListContainerRef.current);
95
+ resizeObserver.observe(tabItemListContainerRef.current!);
69
96
 
70
97
  return () => {
71
98
  resizeObserver.disconnect();
@@ -73,11 +100,11 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
73
100
  }, []);
74
101
 
75
102
  const handleRightClick = () => {
76
- tabItemListContainerRef.current.scrollLeft += 90;
103
+ tabItemListContainerRef.current!.scrollLeft += 90;
77
104
  };
78
105
 
79
106
  const handleLeftClick = () => {
80
- tabItemListContainerRef.current.scrollLeft -= 90;
107
+ tabItemListContainerRef.current!.scrollLeft -= 90;
81
108
  };
82
109
 
83
110
  return (
@@ -116,7 +143,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
116
143
  className={clsx(
117
144
  "tabs__item",
118
145
  "openapi-tabs__discriminator-item",
119
- attributes?.className,
146
+ attributes?.className as string,
120
147
  {
121
148
  active: selectedValue === value,
122
149
  }
@@ -138,12 +165,18 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
138
165
  </div>
139
166
  );
140
167
  }
141
- function TabContent({ lazy, children, selectedValue }) {
142
- // eslint-disable-next-line no-param-reassign
143
- children = Array.isArray(children) ? children : [children];
144
- const flattenedChildren = flatten(children);
168
+
169
+ function TabContent({
170
+ lazy,
171
+ children,
172
+ selectedValue,
173
+ }: TabProps & ReturnType<typeof useTabs>): React.JSX.Element | null {
174
+ const childTabs = (Array.isArray(children) ? children : [children]).filter(
175
+ Boolean
176
+ ) as ReactElement<TabItemProps>[];
177
+ const flattenedChildTabs = flatten(childTabs);
145
178
  if (lazy) {
146
- const selectedTabItem = flattenedChildren.find(
179
+ const selectedTabItem = flattenedChildTabs.find(
147
180
  (tabItem) => tabItem.props.value === selectedValue
148
181
  );
149
182
  if (!selectedTabItem) {
@@ -154,7 +187,7 @@ function TabContent({ lazy, children, selectedValue }) {
154
187
  }
155
188
  return (
156
189
  <div className="margin-top--md">
157
- {children.map((tabItem, i) =>
190
+ {childTabs.map((tabItem, i) =>
158
191
  cloneElement(tabItem, {
159
192
  key: i,
160
193
  hidden: tabItem.props.value !== selectedValue,
@@ -163,7 +196,7 @@ function TabContent({ lazy, children, selectedValue }) {
163
196
  </div>
164
197
  );
165
198
  }
166
- function TabsComponent(props) {
199
+ function TabsComponent(props: TabProps): React.JSX.Element {
167
200
  const tabs = useTabs(props);
168
201
  return (
169
202
  <div className="openapi-tabs__container">
@@ -172,7 +205,7 @@ function TabsComponent(props) {
172
205
  </div>
173
206
  );
174
207
  }
175
- export default function DiscriminatorTabs(props) {
208
+ export default function DiscriminatorTabs(props: TabProps): React.JSX.Element {
176
209
  const isBrowser = useIsBrowser();
177
210
  return (
178
211
  <TabsComponent
@@ -180,6 +213,8 @@ export default function DiscriminatorTabs(props) {
180
213
  // Temporary fix for https://github.com/facebook/docusaurus/issues/5653
181
214
  key={String(isBrowser)}
182
215
  {...props}
183
- />
216
+ >
217
+ {sanitizeTabsChildren(props.children)}
218
+ </TabsComponent>
184
219
  );
185
220
  }
@@ -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
+ import CodeBlock from "@theme/CodeBlock";
11
+ import ReactMarkdown from "react-markdown";
12
+ import rehypeRaw from "rehype-raw";
13
+
14
+ function Markdown({ children }) {
15
+ return (
16
+ <div>
17
+ <ReactMarkdown
18
+ children={children}
19
+ rehypePlugins={[rehypeRaw]}
20
+ components={{
21
+ pre: "div",
22
+ code({ node, inline, className, children, ...props }) {
23
+ const match = /language-(\w+)/.exec(className || "");
24
+ if (inline) return <code>{children}</code>;
25
+ return !inline && match ? (
26
+ <CodeBlock className={className}>{children}</CodeBlock>
27
+ ) : (
28
+ <CodeBlock>{children}</CodeBlock>
29
+ );
30
+ },
31
+ }}
32
+ />
33
+ </div>
34
+ );
35
+ }
36
+
37
+ export default Markdown;
@@ -5,18 +5,32 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import React, { cloneElement, useEffect, useState, useRef } from "react";
8
+ import React, {
9
+ cloneElement,
10
+ useEffect,
11
+ useState,
12
+ useRef,
13
+ ReactElement,
14
+ } from "react";
9
15
 
10
16
  import {
17
+ sanitizeTabsChildren,
18
+ TabProps,
11
19
  useScrollPositionBlocker,
12
20
  useTabs,
13
21
  } from "@docusaurus/theme-common/internal";
22
+ import { TabItemProps } from "@docusaurus/theme-common/lib/utils/tabsUtils";
14
23
  import useIsBrowser from "@docusaurus/useIsBrowser";
15
- import { setAccept } from "@theme/ApiExplorer/Accept/slice";
24
+ import setAccept from "@theme/ApiExplorer/Accept/slice";
16
25
  import { setContentType } from "@theme/ApiExplorer/ContentType/slice";
17
26
  import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
27
+ import { RootState } from "@theme/ApiItem/store";
18
28
  import clsx from "clsx";
19
29
 
30
+ export interface Props {
31
+ schemaType: any;
32
+ }
33
+
20
34
  function TabList({
21
35
  className,
22
36
  block,
@@ -24,8 +38,8 @@ function TabList({
24
38
  selectValue,
25
39
  tabValues,
26
40
  schemaType,
27
- }) {
28
- const tabRefs = [];
41
+ }: Props & TabProps & ReturnType<typeof useTabs>): React.JSX.Element {
42
+ const tabRefs: (HTMLLIElement | null)[] = [];
29
43
  const { blockElementScrollPositionUntilNextRender } =
30
44
  useScrollPositionBlocker();
31
45
 
@@ -34,8 +48,12 @@ function TabList({
34
48
  const isRequestSchema = schemaType?.toLowerCase() === "request";
35
49
 
36
50
  const [selectedValue, setSelectedValue] = useState(selectedValueProp);
37
- const contentTypeVal = useTypedSelector((state) => state.contentType.value);
38
- const acceptTypeVal = useTypedSelector((state) => state.accept.value);
51
+ const contentTypeVal = useTypedSelector(
52
+ (state: RootState) => state.contentType.value
53
+ );
54
+ const acceptTypeVal = useTypedSelector(
55
+ (state: RootState) => state.accept.value
56
+ );
39
57
 
40
58
  useEffect(() => {
41
59
  if (tabRefs.length > 1) {
@@ -48,7 +66,12 @@ function TabList({
48
66
  // eslint-disable-next-line react-hooks/exhaustive-deps
49
67
  }, [contentTypeVal, acceptTypeVal]);
50
68
 
51
- const handleTabChange = (event) => {
69
+ const handleTabChange = (
70
+ event:
71
+ | React.FocusEvent<HTMLLIElement>
72
+ | React.MouseEvent<HTMLLIElement>
73
+ | React.KeyboardEvent<HTMLLIElement>
74
+ ) => {
52
75
  event.preventDefault();
53
76
  const newTab = event.currentTarget;
54
77
  const newTabIndex = tabRefs.indexOf(newTab);
@@ -65,8 +88,9 @@ function TabList({
65
88
  }
66
89
  };
67
90
 
68
- const handleKeydown = (event) => {
69
- let focusElement = null;
91
+ const handleKeydown = (event: React.KeyboardEvent<HTMLLIElement>) => {
92
+ let focusElement: HTMLLIElement | null = null;
93
+
70
94
  switch (event.key) {
71
95
  case "Enter": {
72
96
  handleTabChange(event);
@@ -74,35 +98,38 @@ function TabList({
74
98
  }
75
99
  case "ArrowRight": {
76
100
  const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
77
- focusElement = tabRefs[nextTab] ?? tabRefs[0];
101
+ focusElement = tabRefs[nextTab] ?? tabRefs[0]!;
78
102
  break;
79
103
  }
80
104
  case "ArrowLeft": {
81
105
  const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
82
- focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1];
106
+ focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!;
83
107
  break;
84
108
  }
85
109
  default:
86
110
  break;
87
111
  }
112
+
88
113
  focusElement?.focus();
89
114
  };
90
115
 
91
- const tabItemListContainerRef = useRef(null);
92
- const [showTabArrows, setShowTabArrows] = useState(false);
116
+ const tabItemListContainerRef = useRef<HTMLUListElement>(null);
117
+ const [showTabArrows, setShowTabArrows] = useState<boolean>(false);
93
118
 
94
119
  useEffect(() => {
95
120
  const resizeObserver = new ResizeObserver((entries) => {
96
121
  for (let entry of entries) {
97
- if (entry.target.offsetWidth < entry.target.scrollWidth) {
98
- setShowTabArrows(true);
99
- } else {
100
- setShowTabArrows(false);
101
- }
122
+ requestAnimationFrame(() => {
123
+ if (entry.target.clientWidth < entry.target.scrollWidth) {
124
+ setShowTabArrows(true);
125
+ } else {
126
+ setShowTabArrows(false);
127
+ }
128
+ });
102
129
  }
103
130
  });
104
131
 
105
- resizeObserver.observe(tabItemListContainerRef.current);
132
+ resizeObserver.observe(tabItemListContainerRef.current!);
106
133
 
107
134
  return () => {
108
135
  resizeObserver.disconnect();
@@ -110,11 +137,11 @@ function TabList({
110
137
  }, []);
111
138
 
112
139
  const handleRightClick = () => {
113
- tabItemListContainerRef.current.scrollLeft += 90;
140
+ tabItemListContainerRef.current!.scrollLeft += 90;
114
141
  };
115
142
 
116
143
  const handleLeftClick = () => {
117
- tabItemListContainerRef.current.scrollLeft -= 90;
144
+ tabItemListContainerRef.current!.scrollLeft -= 90;
118
145
  };
119
146
 
120
147
  return (
@@ -154,7 +181,7 @@ function TabList({
154
181
  className={clsx(
155
182
  "tabs__item",
156
183
  "openapi-tabs__mime-item",
157
- attributes?.className,
184
+ attributes?.className as string,
158
185
  {
159
186
  active: selectedValue === value,
160
187
  }
@@ -175,11 +202,16 @@ function TabList({
175
202
  </div>
176
203
  );
177
204
  }
178
- function TabContent({ lazy, children, selectedValue }) {
179
- // eslint-disable-next-line no-param-reassign
180
- children = Array.isArray(children) ? children : [children];
205
+ function TabContent({
206
+ lazy,
207
+ children,
208
+ selectedValue,
209
+ }: Props & TabProps & ReturnType<typeof useTabs>) {
210
+ const childTabs = (Array.isArray(children) ? children : [children]).filter(
211
+ Boolean
212
+ ) as ReactElement<TabItemProps>[];
181
213
  if (lazy) {
182
- const selectedTabItem = children.find(
214
+ const selectedTabItem = childTabs.find(
183
215
  (tabItem) => tabItem.props.value === selectedValue
184
216
  );
185
217
  if (!selectedTabItem) {
@@ -190,7 +222,7 @@ function TabContent({ lazy, children, selectedValue }) {
190
222
  }
191
223
  return (
192
224
  <div className="margin-top--md">
193
- {children.map((tabItem, i) =>
225
+ {childTabs.map((tabItem, i) =>
194
226
  cloneElement(tabItem, {
195
227
  key: i,
196
228
  hidden: tabItem.props.value !== selectedValue,
@@ -199,7 +231,7 @@ function TabContent({ lazy, children, selectedValue }) {
199
231
  </div>
200
232
  );
201
233
  }
202
- function TabsComponent(props) {
234
+ function TabsComponent(props: Props & TabProps): React.JSX.Element {
203
235
  const tabs = useTabs(props);
204
236
  return (
205
237
  <div className="tabs-container">
@@ -208,7 +240,7 @@ function TabsComponent(props) {
208
240
  </div>
209
241
  );
210
242
  }
211
- export default function MimeTabs(props) {
243
+ export default function MimeTabs(props: Props & TabProps) {
212
244
  const isBrowser = useIsBrowser();
213
245
  return (
214
246
  <TabsComponent
@@ -216,6 +248,8 @@ export default function MimeTabs(props) {
216
248
  // Temporary fix for https://github.com/facebook/docusaurus/issues/5653
217
249
  key={String(isBrowser)}
218
250
  {...props}
219
- />
251
+ >
252
+ {sanitizeTabsChildren(props.children)}
253
+ </TabsComponent>
220
254
  );
221
255
  }
@@ -0,0 +1,71 @@
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
+ overflow: hidden;
12
+ }
13
+
14
+ .openapi-tabs__operation-header {
15
+ margin-bottom: 0;
16
+ }
17
+
18
+ .openapi-tabs__operation-item {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: 0.35rem 0.7rem;
23
+ border: 1px solid transparent;
24
+ margin-top: 0 !important;
25
+ margin-right: 0.5rem;
26
+ font-weight: var(--ifm-font-weight-bold);
27
+ font-size: 12px;
28
+ white-space: nowrap;
29
+ transition: 300ms;
30
+
31
+ &:hover {
32
+ background-color: transparent;
33
+ border: 1px solid var(--ifm-toc-border-color);
34
+ }
35
+
36
+ &.active {
37
+ border: 1px solid var(--ifm-tabs-color-active-border);
38
+ color: var(--ifm-tabs-color-active);
39
+ }
40
+
41
+ &:last-child {
42
+ margin-right: 0 !important;
43
+ }
44
+ }
45
+
46
+ .openapi-tabs__operation-list-container {
47
+ overflow-y: hidden;
48
+ overflow-x: scroll;
49
+ scroll-behavior: smooth;
50
+
51
+ &::-webkit-scrollbar {
52
+ display: none;
53
+ }
54
+ }
55
+
56
+ .openapi-tabs__operation-schema-container {
57
+ max-width: 600px;
58
+ }
59
+
60
+ @media screen and (max-width: 500px) {
61
+ .operationTabsTopSection {
62
+ flex-direction: column;
63
+ align-items: flex-start;
64
+ }
65
+
66
+ .operationTabsContainer {
67
+ width: 100%;
68
+ margin-top: var(--ifm-spacing-vertical);
69
+ padding: 0;
70
+ }
71
+ }