docusaurus-theme-openapi-docs 3.0.0-beta.3 → 3.0.0-beta.5

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 (115) hide show
  1. package/lib/markdown/utils.d.ts +2 -1
  2. package/lib/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/index.d.ts +13 -0
  3. package/lib/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/index.js +199 -124
  4. package/lib/theme/ApiExplorer/Accept/index.d.ts +2 -2
  5. package/lib/theme/ApiExplorer/ApiCodeBlock/Container/index.d.ts +4 -0
  6. package/lib/theme/ApiExplorer/ApiCodeBlock/Container/index.js +25 -19
  7. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/Element.d.ts +4 -0
  8. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/Element.js +27 -16
  9. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.d.ts +4 -0
  10. package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.js +115 -96
  11. package/lib/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.d.ts +3 -0
  12. package/lib/theme/ApiExplorer/ApiCodeBlock/CopyButton/index.js +115 -54
  13. package/lib/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.d.ts +6 -0
  14. package/lib/theme/ApiExplorer/ApiCodeBlock/ExitButton/index.js +41 -30
  15. package/lib/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.d.ts +14 -0
  16. package/lib/theme/ApiExplorer/ApiCodeBlock/ExpandButton/index.js +200 -120
  17. package/lib/theme/ApiExplorer/ApiCodeBlock/Line/index.d.ts +3 -0
  18. package/lib/theme/ApiExplorer/ApiCodeBlock/Line/index.js +36 -24
  19. package/lib/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.d.ts +7 -0
  20. package/lib/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/index.js +35 -28
  21. package/lib/theme/ApiExplorer/ApiCodeBlock/index.d.ts +3 -0
  22. package/lib/theme/ApiExplorer/ApiCodeBlock/index.js +72 -14
  23. package/lib/theme/ApiExplorer/Authorization/index.d.ts +2 -2
  24. package/lib/theme/ApiExplorer/Body/index.d.ts +2 -2
  25. package/lib/theme/ApiExplorer/Body/index.js +8 -1
  26. package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.d.ts +21 -0
  27. package/lib/theme/ApiExplorer/CodeSnippets/code-snippets-types.js +8 -0
  28. package/lib/theme/ApiExplorer/CodeSnippets/index.d.ts +4 -14
  29. package/lib/theme/ApiExplorer/CodeSnippets/index.js +87 -8
  30. package/lib/theme/ApiExplorer/CodeSnippets/languages.d.ts +2 -0
  31. package/lib/theme/ApiExplorer/CodeSnippets/languages.js +32 -0
  32. package/lib/theme/ApiExplorer/CodeSnippets/languages.json +0 -96
  33. package/lib/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +14 -0
  34. package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +14 -0
  35. package/lib/theme/ApiExplorer/CodeTabs/index.js +130 -78
  36. package/lib/theme/ApiExplorer/ContentType/index.d.ts +2 -2
  37. package/lib/theme/ApiExplorer/Export/index.d.ts +2 -2
  38. package/lib/theme/ApiExplorer/FloatingButton/index.d.ts +1 -1
  39. package/lib/theme/ApiExplorer/FormFileUpload/index.d.ts +2 -2
  40. package/lib/theme/ApiExplorer/FormItem/index.d.ts +1 -1
  41. package/lib/theme/ApiExplorer/FormMultiSelect/index.d.ts +1 -1
  42. package/lib/theme/ApiExplorer/FormSelect/index.d.ts +1 -1
  43. package/lib/theme/ApiExplorer/FormTextInput/index.d.ts +1 -1
  44. package/lib/theme/ApiExplorer/MethodEndpoint/index.d.ts +2 -2
  45. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.d.ts +2 -2
  46. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.d.ts +2 -2
  47. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.d.ts +2 -2
  48. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.d.ts +2 -2
  49. package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.d.ts +2 -2
  50. package/lib/theme/ApiExplorer/ParamOptions/index.d.ts +2 -2
  51. package/lib/theme/ApiExplorer/Request/index.d.ts +2 -2
  52. package/lib/theme/ApiExplorer/Response/index.d.ts +2 -2
  53. package/lib/theme/ApiExplorer/SecuritySchemes/index.d.ts +2 -2
  54. package/lib/theme/ApiExplorer/Server/index.d.ts +2 -2
  55. package/lib/theme/ApiExplorer/index.d.ts +2 -2
  56. package/lib/theme/ApiExplorer/index.js +1 -1
  57. package/lib/theme/ApiItem/index.d.ts +2 -2
  58. package/lib/theme/ApiItem/index.js +4 -3
  59. package/lib/theme/ApiItem/store.d.ts +4 -4
  60. package/lib/theme/ApiLogo/index.d.ts +2 -2
  61. package/lib/theme/ApiTabs/index.d.ts +7 -0
  62. package/lib/theme/ApiTabs/index.js +155 -97
  63. package/lib/theme/DiscriminatorTabs/index.d.ts +3 -0
  64. package/lib/theme/DiscriminatorTabs/index.js +146 -94
  65. package/lib/theme/Markdown/index.js +37 -0
  66. package/lib/theme/MimeTabs/index.d.ts +6 -0
  67. package/lib/theme/MimeTabs/index.js +163 -114
  68. package/lib/theme/OperationTabs/_OperationTabs.scss +68 -0
  69. package/lib/theme/OperationTabs/index.d.ts +3 -0
  70. package/lib/theme/OperationTabs/index.js +232 -0
  71. package/lib/theme/ParamsItem/index.d.ts +22 -0
  72. package/lib/theme/ParamsItem/index.js +154 -109
  73. package/lib/theme/ResponseSamples/index.d.ts +8 -0
  74. package/lib/theme/ResponseSamples/index.js +18 -13
  75. package/lib/theme/SchemaItem/index.d.ts +12 -0
  76. package/lib/theme/SchemaItem/index.js +123 -89
  77. package/lib/theme/SchemaTabs/index.d.ts +3 -0
  78. package/lib/theme/SchemaTabs/index.js +142 -91
  79. package/lib/theme/styles.scss +1 -0
  80. package/package.json +4 -4
  81. package/src/markdown/utils.ts +4 -2
  82. package/src/theme/ApiDemoPanel/ApiCodeBlock/ExpandButton/{index.js → index.tsx} +21 -8
  83. package/src/theme/ApiExplorer/ApiCodeBlock/Container/{index.js → index.tsx} +6 -3
  84. package/src/theme/ApiExplorer/ApiCodeBlock/Content/{Element.js → Element.tsx} +5 -1
  85. package/src/theme/ApiExplorer/ApiCodeBlock/Content/{String.js → String.tsx} +4 -4
  86. package/src/theme/ApiExplorer/ApiCodeBlock/CopyButton/{index.js → index.tsx} +8 -3
  87. package/src/theme/ApiExplorer/ApiCodeBlock/ExitButton/{index.js → index.tsx} +9 -1
  88. package/src/theme/ApiExplorer/ApiCodeBlock/ExpandButton/{index.js → index.tsx} +12 -2
  89. package/src/theme/ApiExplorer/ApiCodeBlock/Line/{index.js → index.tsx} +2 -1
  90. package/src/theme/ApiExplorer/ApiCodeBlock/WordWrapButton/{index.js → index.tsx} +11 -1
  91. package/src/theme/ApiExplorer/ApiCodeBlock/{index.js → index.tsx} +10 -5
  92. package/src/theme/ApiExplorer/Body/index.tsx +3 -1
  93. package/src/theme/ApiExplorer/CodeSnippets/code-snippets-types.ts +55 -0
  94. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +94 -21
  95. package/src/theme/ApiExplorer/CodeSnippets/languages.json +0 -96
  96. package/src/theme/ApiExplorer/CodeSnippets/languages.ts +37 -0
  97. package/src/theme/ApiExplorer/CodeTabs/_CodeTabs.scss +14 -0
  98. package/src/theme/ApiExplorer/CodeTabs/{index.js → index.tsx} +57 -25
  99. package/src/theme/ApiExplorer/index.tsx +1 -1
  100. package/src/theme/ApiItem/index.tsx +3 -4
  101. package/src/theme/ApiLogo/index.tsx +1 -1
  102. package/src/theme/ApiTabs/{index.js → index.tsx} +63 -25
  103. package/src/theme/DiscriminatorTabs/{index.js → index.tsx} +57 -24
  104. package/src/theme/Markdown/index.js +37 -0
  105. package/src/theme/MimeTabs/{index.js → index.tsx} +58 -26
  106. package/src/theme/OperationTabs/_OperationTabs.scss +68 -0
  107. package/src/theme/OperationTabs/index.tsx +216 -0
  108. package/src/theme/ParamsItem/{index.js → index.tsx} +28 -13
  109. package/src/theme/ResponseSamples/{index.js → index.tsx} +10 -1
  110. package/src/theme/SchemaItem/{index.js → index.tsx} +18 -9
  111. package/src/theme/SchemaTabs/{index.js → index.tsx} +56 -25
  112. package/src/theme/styles.scss +1 -0
  113. package/src/theme-classic.d.ts +69 -2
  114. package/src/theme-openapi.d.ts +4 -0
  115. package/tsconfig.json +4 -1
@@ -27,7 +27,7 @@ function ApiExplorer({
27
27
  {item.method !== "event" && (
28
28
  <CodeSnippets
29
29
  postman={postman}
30
- codeSamples={(item as any)["x-code-samples"] ?? []}
30
+ codeSamples={(item as any)["x-codeSamples"] ?? []}
31
31
  />
32
32
  )}
33
33
  <Request item={item} />
@@ -12,6 +12,7 @@ import React from "react";
12
12
  import BrowserOnly from "@docusaurus/BrowserOnly";
13
13
  import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
14
14
  import { HtmlClassNameProvider } from "@docusaurus/theme-common";
15
+ import { DocProvider } from "@docusaurus/theme-common/internal";
15
16
  import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
16
17
  import useIsBrowser from "@docusaurus/useIsBrowser";
17
18
  import { createAuth } from "@theme/ApiExplorer/Authorization/slice";
@@ -23,7 +24,6 @@ import clsx from "clsx";
23
24
  import { ServerObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
24
25
  import { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
25
26
  import type { ApiItem as ApiItemType } from "docusaurus-plugin-openapi-docs/src/types";
26
- /* eslint-disable import/no-extraneous-dependencies*/
27
27
  import type {
28
28
  DocFrontMatter,
29
29
  ThemeConfig,
@@ -32,8 +32,6 @@ import { Provider } from "react-redux";
32
32
 
33
33
  import { createStoreWithoutState, createStoreWithState } from "./store";
34
34
 
35
- const { DocProvider } = require("@docusaurus/theme-common/internal");
36
-
37
35
  let ApiExplorer = (_: { item: any; infoPath: any }) => <div />;
38
36
 
39
37
  if (ExecutionEnvironment.canUseDOM) {
@@ -44,7 +42,8 @@ interface ApiFrontMatter extends DocFrontMatter {
44
42
  readonly api?: ApiItemType;
45
43
  }
46
44
 
47
- export default function ApiItem(props: Props): JSX.Element {
45
+ // @ts-ignore
46
+ export default function ApiItem(props: Props): React.JSX.Element {
48
47
  const docHtmlClassName = `docs-doc-id-${props.content.metadata.id}`;
49
48
  const MDXComponent = props.content;
50
49
  const { frontMatter } = MDXComponent;
@@ -11,7 +11,7 @@ import { useColorMode } from "@docusaurus/theme-common";
11
11
  import useBaseUrl from "@docusaurus/useBaseUrl";
12
12
  import ThemedImage from "@theme/ThemedImage";
13
13
 
14
- export default function ApiLogo(props: any): JSX.Element | undefined {
14
+ export default function ApiLogo(props: any): React.JSX.Element | undefined {
15
15
  const { colorMode } = useColorMode();
16
16
  const { logo, darkLogo } = props;
17
17
  const altText = () => {
@@ -5,33 +5,62 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import React, { cloneElement, useRef, useState, useEffect } from "react";
8
+ import React, {
9
+ cloneElement,
10
+ useRef,
11
+ useState,
12
+ useEffect,
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 Heading from "@theme/Heading";
16
25
  import clsx from "clsx";
17
26
 
18
- function TabList({ className, block, selectedValue, selectValue, tabValues }) {
19
- const tabRefs = [];
27
+ export interface TabListProps extends TabProps {
28
+ label: string;
29
+ id: string;
30
+ }
31
+
32
+ function TabList({
33
+ className,
34
+ block,
35
+ selectedValue,
36
+ selectValue,
37
+ tabValues,
38
+ label = "Responses",
39
+ id = "responses",
40
+ }: TabListProps & ReturnType<typeof useTabs>) {
41
+ const tabRefs: (HTMLLIElement | null)[] = [];
20
42
  const { blockElementScrollPositionUntilNextRender } =
21
43
  useScrollPositionBlocker();
22
44
 
23
- const handleTabChange = (event) => {
45
+ const handleTabChange = (
46
+ event:
47
+ | React.FocusEvent<HTMLLIElement>
48
+ | React.MouseEvent<HTMLLIElement>
49
+ | React.KeyboardEvent<HTMLLIElement>
50
+ ) => {
24
51
  const newTab = event.currentTarget;
25
52
  const newTabIndex = tabRefs.indexOf(newTab);
26
53
  const newTabValue = tabValues[newTabIndex].value;
54
+
27
55
  if (newTabValue !== selectedValue) {
28
56
  blockElementScrollPositionUntilNextRender(newTab);
29
57
  selectValue(newTabValue);
30
58
  }
31
59
  };
32
60
 
33
- const handleKeydown = (event) => {
34
- let focusElement = null;
61
+ const handleKeydown = (event: React.KeyboardEvent<HTMLLIElement>) => {
62
+ let focusElement: HTMLLIElement | null = null;
63
+
35
64
  switch (event.key) {
36
65
  case "Enter": {
37
66
  handleTabChange(event);
@@ -39,27 +68,28 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
39
68
  }
40
69
  case "ArrowRight": {
41
70
  const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
42
- focusElement = tabRefs[nextTab] ?? tabRefs[0];
71
+ focusElement = tabRefs[nextTab] ?? tabRefs[0]!;
43
72
  break;
44
73
  }
45
74
  case "ArrowLeft": {
46
75
  const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
47
- focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1];
76
+ focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!;
48
77
  break;
49
78
  }
50
79
  default:
51
80
  break;
52
81
  }
82
+
53
83
  focusElement?.focus();
54
84
  };
55
85
 
56
- const tabItemListContainerRef = useRef(null);
57
- const [showTabArrows, setShowTabArrows] = useState(false);
86
+ const tabItemListContainerRef = useRef<HTMLUListElement>(null);
87
+ const [showTabArrows, setShowTabArrows] = useState<boolean>(false);
58
88
 
59
89
  useEffect(() => {
60
90
  const resizeObserver = new ResizeObserver((entries) => {
61
91
  for (let entry of entries) {
62
- if (entry.target.offsetWidth < entry.target.scrollWidth) {
92
+ if (entry.target.clientWidth < entry.target.scrollWidth) {
63
93
  setShowTabArrows(true);
64
94
  } else {
65
95
  setShowTabArrows(false);
@@ -67,7 +97,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
67
97
  }
68
98
  });
69
99
 
70
- resizeObserver.observe(tabItemListContainerRef.current);
100
+ resizeObserver.observe(tabItemListContainerRef.current!);
71
101
 
72
102
  return () => {
73
103
  resizeObserver.disconnect();
@@ -75,17 +105,17 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
75
105
  }, []);
76
106
 
77
107
  const handleRightClick = () => {
78
- tabItemListContainerRef.current.scrollLeft += 90;
108
+ tabItemListContainerRef.current!.scrollLeft += 90;
79
109
  };
80
110
 
81
111
  const handleLeftClick = () => {
82
- tabItemListContainerRef.current.scrollLeft -= 90;
112
+ tabItemListContainerRef.current!.scrollLeft -= 90;
83
113
  };
84
114
 
85
115
  return (
86
116
  <div className="openapi-tabs__response-header-section">
87
- <Heading as="h2" id="responses" className="openapi-tabs__response-header">
88
- Responses
117
+ <Heading as="h2" id={id} className="openapi-tabs__response-header">
118
+ {label}
89
119
  </Heading>
90
120
  <div className="openapi-tabs__response-container">
91
121
  {showTabArrows && (
@@ -121,7 +151,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
121
151
  className={clsx(
122
152
  "tabs__item",
123
153
  "openapi-tabs__response-code-item",
124
- attributes?.className,
154
+ attributes?.className as string,
125
155
  parseInt(value) >= 400
126
156
  ? "danger"
127
157
  : parseInt(value) >= 200 && parseInt(value) < 300
@@ -146,11 +176,17 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
146
176
  </div>
147
177
  );
148
178
  }
149
- function TabContent({ lazy, children, selectedValue }) {
150
- // eslint-disable-next-line no-param-reassign
151
- children = Array.isArray(children) ? children : [children];
179
+
180
+ function TabContent({
181
+ lazy,
182
+ children,
183
+ selectedValue,
184
+ }: TabProps & ReturnType<typeof useTabs>): React.JSX.Element | null {
185
+ const childTabs = (Array.isArray(children) ? children : [children]).filter(
186
+ Boolean
187
+ ) as ReactElement<TabItemProps>[];
152
188
  if (lazy) {
153
- const selectedTabItem = children.find(
189
+ const selectedTabItem = childTabs.find(
154
190
  (tabItem) => tabItem.props.value === selectedValue
155
191
  );
156
192
  if (!selectedTabItem) {
@@ -161,7 +197,7 @@ function TabContent({ lazy, children, selectedValue }) {
161
197
  }
162
198
  return (
163
199
  <div className="margin-top--md">
164
- {children.map((tabItem, i) =>
200
+ {childTabs.map((tabItem, i) =>
165
201
  cloneElement(tabItem, {
166
202
  key: i,
167
203
  hidden: tabItem.props.value !== selectedValue,
@@ -170,7 +206,7 @@ function TabContent({ lazy, children, selectedValue }) {
170
206
  </div>
171
207
  );
172
208
  }
173
- function TabsComponent(props) {
209
+ function TabsComponent(props: TabListProps): React.JSX.Element {
174
210
  const tabs = useTabs(props);
175
211
  return (
176
212
  <div className="openapi-tabs__container">
@@ -179,7 +215,7 @@ function TabsComponent(props) {
179
215
  </div>
180
216
  );
181
217
  }
182
- export default function ApiTabs(props) {
218
+ export default function ApiTabs(props: TabListProps): React.JSX.Element {
183
219
  const isBrowser = useIsBrowser();
184
220
  return (
185
221
  <TabsComponent
@@ -187,6 +223,8 @@ export default function ApiTabs(props) {
187
223
  // Temporary fix for https://github.com/facebook/docusaurus/issues/5653
188
224
  key={String(isBrowser)}
189
225
  {...props}
190
- />
226
+ >
227
+ {sanitizeTabsChildren(props.children)}
228
+ </TabsComponent>
191
229
  );
192
230
  }
@@ -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,27 +61,28 @@ 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) {
85
+ if (entry.target.clientWidth < entry.target.scrollWidth) {
61
86
  setShowTabArrows(true);
62
87
  } else {
63
88
  setShowTabArrows(false);
@@ -65,7 +90,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
65
90
  }
66
91
  });
67
92
 
68
- resizeObserver.observe(tabItemListContainerRef.current);
93
+ resizeObserver.observe(tabItemListContainerRef.current!);
69
94
 
70
95
  return () => {
71
96
  resizeObserver.disconnect();
@@ -73,11 +98,11 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
73
98
  }, []);
74
99
 
75
100
  const handleRightClick = () => {
76
- tabItemListContainerRef.current.scrollLeft += 90;
101
+ tabItemListContainerRef.current!.scrollLeft += 90;
77
102
  };
78
103
 
79
104
  const handleLeftClick = () => {
80
- tabItemListContainerRef.current.scrollLeft -= 90;
105
+ tabItemListContainerRef.current!.scrollLeft -= 90;
81
106
  };
82
107
 
83
108
  return (
@@ -116,7 +141,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
116
141
  className={clsx(
117
142
  "tabs__item",
118
143
  "openapi-tabs__discriminator-item",
119
- attributes?.className,
144
+ attributes?.className as string,
120
145
  {
121
146
  active: selectedValue === value,
122
147
  }
@@ -138,12 +163,18 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
138
163
  </div>
139
164
  );
140
165
  }
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);
166
+
167
+ function TabContent({
168
+ lazy,
169
+ children,
170
+ selectedValue,
171
+ }: TabProps & ReturnType<typeof useTabs>): React.JSX.Element | null {
172
+ const childTabs = (Array.isArray(children) ? children : [children]).filter(
173
+ Boolean
174
+ ) as ReactElement<TabItemProps>[];
175
+ const flattenedChildTabs = flatten(childTabs);
145
176
  if (lazy) {
146
- const selectedTabItem = flattenedChildren.find(
177
+ const selectedTabItem = flattenedChildTabs.find(
147
178
  (tabItem) => tabItem.props.value === selectedValue
148
179
  );
149
180
  if (!selectedTabItem) {
@@ -154,7 +185,7 @@ function TabContent({ lazy, children, selectedValue }) {
154
185
  }
155
186
  return (
156
187
  <div className="margin-top--md">
157
- {children.map((tabItem, i) =>
188
+ {childTabs.map((tabItem, i) =>
158
189
  cloneElement(tabItem, {
159
190
  key: i,
160
191
  hidden: tabItem.props.value !== selectedValue,
@@ -163,7 +194,7 @@ function TabContent({ lazy, children, selectedValue }) {
163
194
  </div>
164
195
  );
165
196
  }
166
- function TabsComponent(props) {
197
+ function TabsComponent(props: TabProps): React.JSX.Element {
167
198
  const tabs = useTabs(props);
168
199
  return (
169
200
  <div className="openapi-tabs__container">
@@ -172,7 +203,7 @@ function TabsComponent(props) {
172
203
  </div>
173
204
  );
174
205
  }
175
- export default function DiscriminatorTabs(props) {
206
+ export default function DiscriminatorTabs(props: TabProps): React.JSX.Element {
176
207
  const isBrowser = useIsBrowser();
177
208
  return (
178
209
  <TabsComponent
@@ -180,6 +211,8 @@ export default function DiscriminatorTabs(props) {
180
211
  // Temporary fix for https://github.com/facebook/docusaurus/issues/5653
181
212
  key={String(isBrowser)}
182
213
  {...props}
183
- />
214
+ >
215
+ {sanitizeTabsChildren(props.children)}
216
+ </TabsComponent>
184
217
  );
185
218
  }
@@ -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,27 +98,28 @@ 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) {
122
+ if (entry.target.clientWidth < entry.target.scrollWidth) {
98
123
  setShowTabArrows(true);
99
124
  } else {
100
125
  setShowTabArrows(false);
@@ -102,7 +127,7 @@ function TabList({
102
127
  }
103
128
  });
104
129
 
105
- resizeObserver.observe(tabItemListContainerRef.current);
130
+ resizeObserver.observe(tabItemListContainerRef.current!);
106
131
 
107
132
  return () => {
108
133
  resizeObserver.disconnect();
@@ -110,11 +135,11 @@ function TabList({
110
135
  }, []);
111
136
 
112
137
  const handleRightClick = () => {
113
- tabItemListContainerRef.current.scrollLeft += 90;
138
+ tabItemListContainerRef.current!.scrollLeft += 90;
114
139
  };
115
140
 
116
141
  const handleLeftClick = () => {
117
- tabItemListContainerRef.current.scrollLeft -= 90;
142
+ tabItemListContainerRef.current!.scrollLeft -= 90;
118
143
  };
119
144
 
120
145
  return (
@@ -154,7 +179,7 @@ function TabList({
154
179
  className={clsx(
155
180
  "tabs__item",
156
181
  "openapi-tabs__mime-item",
157
- attributes?.className,
182
+ attributes?.className as string,
158
183
  {
159
184
  active: selectedValue === value,
160
185
  }
@@ -175,11 +200,16 @@ function TabList({
175
200
  </div>
176
201
  );
177
202
  }
178
- function TabContent({ lazy, children, selectedValue }) {
179
- // eslint-disable-next-line no-param-reassign
180
- children = Array.isArray(children) ? children : [children];
203
+ function TabContent({
204
+ lazy,
205
+ children,
206
+ selectedValue,
207
+ }: Props & TabProps & ReturnType<typeof useTabs>) {
208
+ const childTabs = (Array.isArray(children) ? children : [children]).filter(
209
+ Boolean
210
+ ) as ReactElement<TabItemProps>[];
181
211
  if (lazy) {
182
- const selectedTabItem = children.find(
212
+ const selectedTabItem = childTabs.find(
183
213
  (tabItem) => tabItem.props.value === selectedValue
184
214
  );
185
215
  if (!selectedTabItem) {
@@ -190,7 +220,7 @@ function TabContent({ lazy, children, selectedValue }) {
190
220
  }
191
221
  return (
192
222
  <div className="margin-top--md">
193
- {children.map((tabItem, i) =>
223
+ {childTabs.map((tabItem, i) =>
194
224
  cloneElement(tabItem, {
195
225
  key: i,
196
226
  hidden: tabItem.props.value !== selectedValue,
@@ -199,7 +229,7 @@ function TabContent({ lazy, children, selectedValue }) {
199
229
  </div>
200
230
  );
201
231
  }
202
- function TabsComponent(props) {
232
+ function TabsComponent(props: Props & TabProps): React.JSX.Element {
203
233
  const tabs = useTabs(props);
204
234
  return (
205
235
  <div className="tabs-container">
@@ -208,7 +238,7 @@ function TabsComponent(props) {
208
238
  </div>
209
239
  );
210
240
  }
211
- export default function MimeTabs(props) {
241
+ export default function MimeTabs(props: Props & TabProps) {
212
242
  const isBrowser = useIsBrowser();
213
243
  return (
214
244
  <TabsComponent
@@ -216,6 +246,8 @@ export default function MimeTabs(props) {
216
246
  // Temporary fix for https://github.com/facebook/docusaurus/issues/5653
217
247
  key={String(isBrowser)}
218
248
  {...props}
219
- />
249
+ >
250
+ {sanitizeTabsChildren(props.children)}
251
+ </TabsComponent>
220
252
  );
221
253
  }