docusaurus-theme-openapi-docs 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/lib/index.js +2 -11
  2. package/lib/markdown/utils.js +18 -1
  3. package/lib/theme/ApiDemoPanel/Curl/index.js +36 -9
  4. package/lib/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  5. package/lib/theme/ApiDemoPanel/Request/index.js +3 -2
  6. package/lib/theme/ApiDemoPanel/SecuritySchemes/index.js +195 -9
  7. package/lib/theme/ApiLogo/index.js +24 -1
  8. package/lib/theme/ParamsItem/index.js +33 -6
  9. package/lib/theme/SchemaItem/index.js +26 -12
  10. package/lib/theme/SchemaItem/styles.module.css +5 -0
  11. package/lib/theme/SchemaTabs/index.js +2 -2
  12. package/lib/theme/SchemaTabs/styles.module.css +5 -0
  13. package/lib/theme/styles.css +57 -2
  14. package/lib-next/index.js +2 -13
  15. package/lib-next/markdown/utils.js +17 -1
  16. package/lib-next/theme/ApiDemoPanel/Curl/index.js +37 -8
  17. package/lib-next/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  18. package/lib-next/theme/ApiDemoPanel/Request/index.js +4 -2
  19. package/lib-next/theme/ApiDemoPanel/SecuritySchemes/index.js +210 -9
  20. package/lib-next/theme/ApiLogo/index.js +35 -9
  21. package/lib-next/theme/ParamsItem/index.js +33 -6
  22. package/lib-next/theme/SchemaItem/index.js +26 -12
  23. package/lib-next/theme/SchemaItem/styles.module.css +5 -0
  24. package/lib-next/theme/SchemaTabs/index.js +2 -2
  25. package/lib-next/theme/SchemaTabs/styles.module.css +5 -0
  26. package/lib-next/theme/styles.css +57 -2
  27. package/package.json +8 -7
  28. package/src/index.ts +3 -13
  29. package/src/markdown/utils.ts +18 -1
  30. package/src/theme/ApiDemoPanel/Curl/index.tsx +36 -8
  31. package/src/theme/ApiDemoPanel/Curl/styles.module.css +5 -0
  32. package/src/theme/ApiDemoPanel/Request/index.tsx +4 -2
  33. package/src/theme/ApiDemoPanel/SecuritySchemes/index.tsx +213 -9
  34. package/src/theme/ApiLogo/index.tsx +37 -10
  35. package/src/theme/ParamsItem/index.js +33 -6
  36. package/src/theme/SchemaItem/index.js +26 -12
  37. package/src/theme/SchemaItem/styles.module.css +5 -0
  38. package/src/theme/SchemaTabs/index.js +2 -2
  39. package/src/theme/SchemaTabs/styles.module.css +5 -0
  40. package/src/theme/styles.css +57 -2
@@ -8,6 +8,7 @@
8
8
  :root {
9
9
  --openapi-required: var(--ifm-color-danger);
10
10
  --openapi-deprecated: var(--ifm-color-warning);
11
+ --openapi-nullable: var(--ifm-color-info);
11
12
  --openapi-code-blue: var(--ifm-color-info);
12
13
  --openapi-code-red: var(--ifm-color-danger);
13
14
  --openapi-code-orange: var(--ifm-color-warning);
@@ -77,10 +78,14 @@
77
78
 
78
79
  .theme-api-markdown details li {
79
80
  list-style: none;
80
- padding-bottom: 5px;
81
81
  padding-top: 5px;
82
82
  }
83
83
 
84
+ .theme-api-markdown .tabs__item {
85
+ padding-bottom: unset;
86
+ padding-top: unset;
87
+ }
88
+
84
89
  .theme-api-markdown details > div > div {
85
90
  padding-top: unset !important;
86
91
  border-top: unset !important;
@@ -244,6 +249,8 @@
244
249
  color: var(--ifm-color-success);
245
250
  padding-left: 1.4rem;
246
251
  padding-right: 1.4rem;
252
+ padding-top: 1rem !important;
253
+ padding-bottom: 1rem !important;
247
254
  }
248
255
 
249
256
  .code__tab--python.tabs__item--active {
@@ -268,6 +275,8 @@
268
275
  color: var(--ifm-color-info);
269
276
  padding-left: 1.4rem;
270
277
  padding-right: 1.4rem;
278
+ padding-top: 1rem !important;
279
+ padding-bottom: 1rem !important;
271
280
  }
272
281
 
273
282
  .code__tab--go.tabs__item--active {
@@ -292,6 +301,8 @@
292
301
  color: var(--ifm-color-warning);
293
302
  padding-left: 1.4rem;
294
303
  padding-right: 1.4rem;
304
+ padding-top: 1rem !important;
305
+ padding-bottom: 1rem !important;
295
306
  }
296
307
 
297
308
  .code__tab--javascript.tabs__item--active {
@@ -316,6 +327,8 @@
316
327
  color: var(--ifm-color-danger);
317
328
  padding-left: 1.4rem;
318
329
  padding-right: 1.4rem;
330
+ padding-top: 1rem !important;
331
+ padding-bottom: 1rem !important;
319
332
  }
320
333
 
321
334
  .code__tab--bash.tabs__item--active {
@@ -340,6 +353,8 @@
340
353
  color: var(--ifm-color-danger);
341
354
  padding-left: 1.4rem;
342
355
  padding-right: 1.4rem;
356
+ padding-top: 1rem !important;
357
+ padding-bottom: 1rem !important;
343
358
  }
344
359
 
345
360
  .code__tab--ruby.tabs__item--active {
@@ -364,6 +379,8 @@
364
379
  color: var(--ifm-color-gray-500);
365
380
  padding-left: 1.4rem;
366
381
  padding-right: 1.4rem;
382
+ padding-top: 1rem !important;
383
+ padding-bottom: 1rem !important;
367
384
  }
368
385
 
369
386
  .code__tab--csharp.tabs__item--active {
@@ -388,6 +405,8 @@
388
405
  color: var(--ifm-color-success);
389
406
  padding-left: 1.4rem;
390
407
  padding-right: 1.4rem;
408
+ padding-top: 1rem !important;
409
+ padding-bottom: 1rem !important;
391
410
  }
392
411
 
393
412
  .code__tab--nodejs.tabs__item--active {
@@ -412,6 +431,8 @@
412
431
  color: var(--ifm-color-gray-500);
413
432
  padding-left: 1.4rem;
414
433
  padding-right: 1.4rem;
434
+ padding-top: 1rem !important;
435
+ padding-bottom: 1rem !important;
415
436
  }
416
437
 
417
438
  .code__tab--php.tabs__item--active {
@@ -424,7 +445,41 @@
424
445
  overflow: auto;
425
446
  }
426
447
 
448
+ .code__tab--java::after {
449
+ content: "";
450
+ width: 28px;
451
+ height: 28px;
452
+ background: url("https://raw.githubusercontent.com/devicons/devicon/master/icons/java/java-original.svg");
453
+ margin-block: auto;
454
+ }
455
+
456
+ .code__tab--java {
457
+ color: var(--ifm-color-warning);
458
+ padding-left: 1.4rem;
459
+ padding-right: 1.4rem;
460
+ padding-top: 1rem !important;
461
+ padding-bottom: 1rem !important;
462
+ }
463
+
464
+ .code__tab--java.tabs__item--active {
465
+ border-bottom-color: var(--ifm-color-warning);
466
+ background-color: var(--ifm-color-emphasis-100);
467
+ }
468
+
469
+ .language-java {
470
+ max-height: 500px;
471
+ overflow: auto;
472
+ }
473
+
427
474
  /* Prism code styles */
428
- .prism-code.language-json {
475
+ .prism-code.language-java {
429
476
  white-space: pre !important;
430
477
  }
478
+
479
+ .openapi__logo {
480
+ width: 250px;
481
+ }
482
+
483
+ div:has(> ul.openapi-tabs__security-schemes) {
484
+ max-width: 100%;
485
+ }
package/lib-next/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * ========================================================================== */
7
7
 
8
8
  import path from "path";
9
- import { ProvidePlugin } from "webpack";
9
+ const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
10
10
  export default function docusaurusThemeOpenAPI() {
11
11
  return {
12
12
  name: "docusaurus-theme-openapi",
@@ -22,18 +22,7 @@ export default function docusaurusThemeOpenAPI() {
22
22
  },
23
23
  configureWebpack() {
24
24
  return {
25
- plugins: [
26
- new ProvidePlugin({
27
- Buffer: [require.resolve("buffer/"), "Buffer"],
28
- process: require.resolve("process/browser"),
29
- }),
30
- ],
31
- resolve: {
32
- fallback: {
33
- buffer: require.resolve("buffer/"),
34
- process: require.resolve("process/browser"),
35
- },
36
- },
25
+ plugins: [new NodePolyfillPlugin()],
37
26
  };
38
27
  },
39
28
  };
@@ -14,7 +14,7 @@ export function create(tag, props) {
14
14
  return `<${tag}${propString}>${render(children)}</${tag}>`;
15
15
  }
16
16
  export function guard(value, cb) {
17
- if (value) {
17
+ if (value !== undefined) {
18
18
  const children = cb(value);
19
19
  return render(children);
20
20
  }
@@ -26,3 +26,19 @@ export function render(children) {
26
26
  }
27
27
  return children ?? "";
28
28
  }
29
+ export function toString(value) {
30
+ // Return as-is if already string
31
+ if (typeof value === "string") {
32
+ return value;
33
+ }
34
+ // Return undefined if null or undefined
35
+ if (value == null) {
36
+ return undefined;
37
+ }
38
+ // Return formatted array if Array
39
+ if (Array.isArray(value)) {
40
+ return `[${value.join(", ")}]`;
41
+ }
42
+ // Coerce to string in all other cases,
43
+ return value + "";
44
+ }
@@ -13,6 +13,7 @@ import CodeTabs from "@theme/ApiDemoPanel/CodeTabs";
13
13
  import { useTypedSelector } from "@theme/ApiItem/hooks";
14
14
  import CodeBlock from "@theme/CodeBlock";
15
15
  import clsx from "clsx";
16
+ import merge from "lodash/merge";
16
17
  import styles from "./styles.module.css";
17
18
  export const languageSet = [
18
19
  {
@@ -87,6 +88,16 @@ export const languageSet = [
87
88
  },
88
89
  variant: "cURL",
89
90
  },
91
+ {
92
+ highlight: "java",
93
+ language: "java",
94
+ logoClass: "java",
95
+ options: {
96
+ followRedirect: true,
97
+ trimRequestBody: true,
98
+ },
99
+ variant: "OkHttp",
100
+ },
90
101
  ];
91
102
  function CodeTab({ children, hidden, className, onClick }) {
92
103
  return (
@@ -115,20 +126,35 @@ function Curl({ postman, codeSamples }) {
115
126
  const headerParams = useTypedSelector((state) => state.params.header);
116
127
  const auth = useTypedSelector((state) => state.auth);
117
128
 
118
- // TODO
129
+ // User-defined languages array
130
+ // Can override languageSet, change order of langs, override options and variants
119
131
  const langs = [
120
132
  ...(siteConfig?.themeConfig?.languageTabs ?? languageSet),
121
133
  ...codeSamples,
122
134
  ];
123
- const defaultLang = languageSet.filter(
135
+
136
+ // Filter languageSet by user-defined langs
137
+ const filteredLanguageSet = languageSet.filter((ls) => {
138
+ return langs.some((lang) => {
139
+ return lang.language === ls.language;
140
+ });
141
+ });
142
+
143
+ // Merge user-defined langs into languageSet
144
+ const mergedLangs = merge(filteredLanguageSet, langs);
145
+
146
+ // Read defaultLang from localStorage
147
+ const defaultLang = mergedLangs.filter(
124
148
  (lang) =>
125
149
  lang.language === localStorage.getItem("docusaurus.tab.code-samples")
126
150
  );
127
151
  const [language, setLanguage] = useState(() => {
128
- if (langs.length === 1) {
129
- return langs[0];
152
+ // Return first index if only 1 user-defined language exists
153
+ if (mergedLangs.length === 1) {
154
+ return mergedLangs[0];
130
155
  }
131
- return defaultLang[0] ?? langs[0];
156
+ // Fall back to language in localStorage or first user-defined language
157
+ return defaultLang[0] ?? mergedLangs[0];
132
158
  });
133
159
  const [codeText, setCodeText] = useState("");
134
160
  useEffect(() => {
@@ -159,7 +185,7 @@ function Curl({ postman, codeSamples }) {
159
185
  } else if (language && !!language.source) {
160
186
  setCodeText(language.source);
161
187
  } else if (language && !language.options) {
162
- const langSource = languageSet.filter(
188
+ const langSource = mergedLangs.filter(
163
189
  (lang) => lang.language === language.language
164
190
  );
165
191
 
@@ -208,6 +234,7 @@ function Curl({ postman, codeSamples }) {
208
234
  queryParams,
209
235
  server,
210
236
  auth,
237
+ mergedLangs,
211
238
  ]);
212
239
  if (language === undefined) {
213
240
  return null;
@@ -215,7 +242,7 @@ function Curl({ postman, codeSamples }) {
215
242
  return (
216
243
  <>
217
244
  <CodeTabs groupId="code-samples" action={setLanguage}>
218
- {langs.map((lang) => {
245
+ {mergedLangs.map((lang) => {
219
246
  return (
220
247
  <CodeTab
221
248
  value={lang.language}
@@ -229,7 +256,9 @@ function Curl({ postman, codeSamples }) {
229
256
  className: `code__tab--${lang.logoClass}`,
230
257
  }}
231
258
  >
232
- <CodeBlock language={lang.highlight}>{codeText}</CodeBlock>
259
+ <CodeBlock language={lang.highlight} className={styles.codeBlock}>
260
+ {codeText}
261
+ </CodeBlock>
233
262
  </CodeTab>
234
263
  );
235
264
  })}
@@ -82,3 +82,8 @@
82
82
  background: var(--ifm-menu-color-background-active);
83
83
  color: var(--ifm-menu-color-active);
84
84
  }
85
+
86
+ .codeBlock code {
87
+ max-width: revert;
88
+ max-height: revert;
89
+ }
@@ -20,7 +20,7 @@ function Request({ item }) {
20
20
  const response = useTypedSelector((state) => state.response.value);
21
21
  const postman = new sdk.Request(item.postman);
22
22
  const metadata = useDoc();
23
- const { proxy } = metadata.frontMatter;
23
+ const { proxy, hide_send_button } = metadata.frontMatter;
24
24
  const params = {
25
25
  path: [],
26
26
  query: [],
@@ -38,7 +38,9 @@ function Request({ item }) {
38
38
  <summary>
39
39
  <div className={`details__request-summary`}>
40
40
  <h4>Request</h4>
41
- {item.servers && <Execute postman={postman} proxy={proxy} />}
41
+ {item.servers && !hide_send_button && (
42
+ <Execute postman={postman} proxy={proxy} />
43
+ )}
42
44
  </div>
43
45
  </summary>
44
46
  <div className={styles.optionsPanel}>
@@ -13,6 +13,9 @@ function SecuritySchemes(props) {
13
13
  const selected = useTypedSelector((state) => state.auth.selected);
14
14
  const infoAuthPath = `/${props.infoPath}#authentication`;
15
15
  if (selected === undefined) return null;
16
+ if (options[selected]?.[0]?.type === undefined) {
17
+ return null;
18
+ }
16
19
  const selectedAuth = options[selected];
17
20
  return (
18
21
  <details className={`details__demo-panel`} open={false}>
@@ -20,10 +23,93 @@ function SecuritySchemes(props) {
20
23
  <h4>Authorization</h4>
21
24
  </summary>
22
25
  {selectedAuth.map((auth) => {
26
+ const isHttp = auth.type === "http";
23
27
  const isApiKey = auth.type === "apiKey";
24
- const isBearer = auth.type === "http" && auth.key === "Bearer";
25
28
  const isOauth2 = auth.type === "oauth2";
26
- if (isApiKey || isBearer) {
29
+ const isOpenId = auth.type === "openIdConnect";
30
+ if (isHttp) {
31
+ if (auth.scheme === "bearer") {
32
+ const { name, key, type, scopes, ...rest } = auth;
33
+ return (
34
+ <React.Fragment key={auth.key}>
35
+ <pre
36
+ style={{
37
+ display: "flex",
38
+ flexDirection: "column",
39
+ background: "var(--openapi-card-background-color)",
40
+ }}
41
+ >
42
+ <span>
43
+ <strong>name:</strong>{" "}
44
+ <Link to={infoAuthPath}>{name ?? key}</Link>
45
+ </span>
46
+ <span>
47
+ <strong>type: </strong>
48
+ {type}
49
+ </span>
50
+ {scopes && scopes.length > 0 && (
51
+ <span>
52
+ <strong>scopes: </strong>
53
+ <code>
54
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
55
+ </code>
56
+ </span>
57
+ )}
58
+ {Object.keys(rest).map((k, i) => {
59
+ return (
60
+ <span key={k}>
61
+ <strong>{k}: </strong>
62
+ {typeof rest[k] === "object"
63
+ ? JSON.stringify(rest[k], null, 2)
64
+ : String(rest[k])}
65
+ </span>
66
+ );
67
+ })}
68
+ </pre>
69
+ </React.Fragment>
70
+ );
71
+ }
72
+ if (auth.scheme === "basic") {
73
+ const { name, key, type, scopes, ...rest } = auth;
74
+ return (
75
+ <React.Fragment key={auth.key}>
76
+ <pre
77
+ style={{
78
+ display: "flex",
79
+ flexDirection: "column",
80
+ background: "var(--openapi-card-background-color)",
81
+ }}
82
+ >
83
+ <span>
84
+ <strong>name:</strong>{" "}
85
+ <Link to={infoAuthPath}>{name ?? key}</Link>
86
+ </span>
87
+ <span>
88
+ <strong>type: </strong>
89
+ {type}
90
+ </span>
91
+ {scopes && scopes.length > 0 && (
92
+ <span>
93
+ <strong>scopes: </strong>
94
+ <code>
95
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
96
+ </code>
97
+ </span>
98
+ )}
99
+ {Object.keys(rest).map((k, i) => {
100
+ return (
101
+ <span key={k}>
102
+ <strong>{k}: </strong>
103
+ {typeof rest[k] === "object"
104
+ ? JSON.stringify(rest[k], null, 2)
105
+ : String(rest[k])}
106
+ </span>
107
+ );
108
+ })}
109
+ </pre>
110
+ </React.Fragment>
111
+ );
112
+ }
27
113
  return (
28
114
  <React.Fragment key={auth.key}>
29
115
  <pre
@@ -33,16 +119,65 @@ function SecuritySchemes(props) {
33
119
  background: "var(--openapi-card-background-color)",
34
120
  }}
35
121
  >
36
- <span>type: {auth.type}</span>
37
122
  <span>
38
- name: <Link to={infoAuthPath}>{auth.name}</Link>
123
+ <strong>name:</strong>{" "}
124
+ <Link to={infoAuthPath}>{auth.name ?? auth.key}</Link>
39
125
  </span>
40
- <span>in: {auth.in}</span>
126
+ <span>
127
+ <strong>type: </strong>
128
+ {auth.type}
129
+ </span>
130
+ <span>
131
+ <strong>in: </strong>
132
+ {auth.in}
133
+ </span>
134
+ </pre>
135
+ </React.Fragment>
136
+ );
137
+ }
138
+ if (isApiKey) {
139
+ const { name, key, type, scopes, ...rest } = auth;
140
+ return (
141
+ <React.Fragment key={auth.key}>
142
+ <pre
143
+ style={{
144
+ display: "flex",
145
+ flexDirection: "column",
146
+ background: "var(--openapi-card-background-color)",
147
+ }}
148
+ >
149
+ <span>
150
+ <strong>name:</strong>{" "}
151
+ <Link to={infoAuthPath}>{name ?? key}</Link>
152
+ </span>
153
+ <span>
154
+ <strong>type: </strong>
155
+ {type}
156
+ </span>
157
+ {scopes && scopes.length > 0 && (
158
+ <span>
159
+ <strong>scopes: </strong>
160
+ <code>
161
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
162
+ </code>
163
+ </span>
164
+ )}
165
+ {Object.keys(rest).map((k, i) => {
166
+ return (
167
+ <span key={k}>
168
+ <strong>{k}: </strong>
169
+ {typeof rest[k] === "object"
170
+ ? JSON.stringify(rest[k], null, 2)
171
+ : String(rest[k])}
172
+ </span>
173
+ );
174
+ })}
41
175
  </pre>
42
176
  </React.Fragment>
43
177
  );
44
178
  }
45
179
  if (isOauth2) {
180
+ const { name, key, type, scopes, flows, ...rest } = auth;
46
181
  return (
47
182
  <React.Fragment key={selected}>
48
183
  <pre
@@ -53,14 +188,80 @@ function SecuritySchemes(props) {
53
188
  }}
54
189
  >
55
190
  <span>
56
- type: <Link to={infoAuthPath}>{auth.type}</Link>
191
+ <strong>name:</strong>{" "}
192
+ <Link to={infoAuthPath}>{name ?? key}</Link>
57
193
  </span>
58
- {Object.keys(auth.flows).map((flow) => {
59
- return <span key={flow}>flow: {flow}</span>;
194
+ <span>
195
+ <strong>type: </strong>
196
+ {type}
197
+ </span>
198
+ {scopes && scopes.length > 0 && (
199
+ <span>
200
+ <strong>scopes: </strong>
201
+ <code>
202
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
203
+ </code>
204
+ </span>
205
+ )}
206
+ {Object.keys(rest).map((k, i) => {
207
+ return (
208
+ <span key={k}>
209
+ <strong>{k}: </strong>
210
+ {typeof rest[k] === "object"
211
+ ? JSON.stringify(rest[k], null, 2)
212
+ : String(rest[k])}
213
+ </span>
214
+ );
60
215
  })}
216
+ {flows && (
217
+ <span>
218
+ <code>
219
+ <strong>flows: </strong>
220
+ {JSON.stringify(flows, null, 2)}
221
+ </code>
222
+ </span>
223
+ )}
224
+ </pre>
225
+ </React.Fragment>
226
+ );
227
+ }
228
+ if (isOpenId) {
229
+ const { name, key, scopes, type, ...rest } = auth;
230
+ return (
231
+ <React.Fragment key={auth.key}>
232
+ <pre
233
+ style={{
234
+ display: "flex",
235
+ flexDirection: "column",
236
+ background: "var(--openapi-card-background-color)",
237
+ }}
238
+ >
61
239
  <span>
62
- scopes: <code>{auth.scopes.toString()}</code>
240
+ <strong>name:</strong>{" "}
241
+ <Link to={infoAuthPath}>{name ?? key}</Link>
63
242
  </span>
243
+ <span>
244
+ <strong>type: </strong>
245
+ {type}
246
+ </span>
247
+ {scopes && scopes.length > 0 && (
248
+ <span>
249
+ <strong>scopes: </strong>
250
+ <code>
251
+ {auth.scopes.length > 0 ? auth.scopes.toString() : "[]"}
252
+ </code>
253
+ </span>
254
+ )}
255
+ {Object.keys(rest).map((k, i) => {
256
+ return (
257
+ <span key={k}>
258
+ <strong>{k}: </strong>
259
+ {typeof rest[k] === "object"
260
+ ? JSON.stringify(rest[k], null, 2)
261
+ : String(rest[k])}
262
+ </span>
263
+ );
264
+ })}
64
265
  </pre>
65
266
  </React.Fragment>
66
267
  );
@@ -7,16 +7,42 @@
7
7
 
8
8
  import React from "react";
9
9
  import { useColorMode } from "@docusaurus/theme-common";
10
+ import useBaseUrl from "@docusaurus/useBaseUrl";
11
+ import ThemedImage from "@theme/ThemedImage";
10
12
  export default function ApiLogo(props) {
11
13
  const { colorMode } = useColorMode();
12
14
  const { logo, darkLogo } = props;
13
- return logo ? (
14
- <img
15
- alt={colorMode === "dark" && darkLogo ? darkLogo.altText : logo.altText}
16
- src={colorMode === "dark" && darkLogo ? darkLogo.url : logo.url}
17
- width="250px"
18
- />
19
- ) : (
20
- <div />
21
- );
15
+ const altText = () => {
16
+ if (colorMode === "dark") {
17
+ return darkLogo?.altText ?? logo?.altText;
18
+ }
19
+ return logo?.altText;
20
+ };
21
+ const lightLogoUrl = useBaseUrl(logo?.url);
22
+ const darkLogoUrl = useBaseUrl(darkLogo?.url);
23
+ if (logo && darkLogo) {
24
+ return (
25
+ <ThemedImage
26
+ alt={altText()}
27
+ sources={{
28
+ light: lightLogoUrl,
29
+ dark: darkLogoUrl,
30
+ }}
31
+ className="openapi__logo"
32
+ />
33
+ );
34
+ }
35
+ if (logo || darkLogo) {
36
+ return (
37
+ <ThemedImage
38
+ alt={altText()}
39
+ sources={{
40
+ light: lightLogoUrl ?? darkLogoUrl,
41
+ dark: lightLogoUrl ?? darkLogoUrl,
42
+ }}
43
+ className="openapi__logo"
44
+ />
45
+ );
46
+ }
47
+ return undefined;
22
48
  }