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

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 (32) hide show
  1. package/lib/markdown/utils.js +1 -1
  2. package/lib/markdown/utils.test.d.ts +1 -0
  3. package/lib/markdown/utils.test.js +43 -0
  4. package/lib/theme/ApiExplorer/CodeSnippets/index.js +10 -11
  5. package/lib/theme/ApiExplorer/CodeSnippets/languages.d.ts +1 -0
  6. package/lib/theme/ApiExplorer/CodeSnippets/languages.js +17 -1
  7. package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +3 -2
  8. package/lib/theme/ApiExplorer/CodeTabs/index.js +10 -7
  9. package/lib/theme/ApiItem/index.d.ts +2 -2
  10. package/lib/theme/ApiItem/index.js +24 -0
  11. package/lib/theme/ApiTabs/_ApiTabs.scss +3 -1
  12. package/lib/theme/ApiTabs/index.js +5 -1
  13. package/lib/theme/OperationTabs/_OperationTabs.scss +4 -1
  14. package/lib/theme/ParamsItem/index.d.ts +2 -1
  15. package/lib/theme/ParamsItem/index.js +18 -4
  16. package/lib/theme/SchemaItem/index.js +9 -11
  17. package/lib/theme/SchemaTabs/_SchemaTabs.scss +0 -4
  18. package/lib/theme/styles.scss +4 -0
  19. package/package.json +3 -3
  20. package/src/markdown/utils.test.ts +49 -0
  21. package/src/markdown/utils.ts +1 -1
  22. package/src/theme/ApiExplorer/CodeSnippets/index.tsx +13 -13
  23. package/src/theme/ApiExplorer/CodeSnippets/languages.ts +16 -0
  24. package/src/theme/ApiExplorer/CodeTabs/index.tsx +17 -10
  25. package/src/theme/ApiItem/index.tsx +21 -1
  26. package/src/theme/ApiTabs/_ApiTabs.scss +3 -1
  27. package/src/theme/ApiTabs/index.tsx +5 -1
  28. package/src/theme/OperationTabs/_OperationTabs.scss +4 -1
  29. package/src/theme/ParamsItem/index.tsx +19 -3
  30. package/src/theme/SchemaItem/index.tsx +6 -9
  31. package/src/theme/SchemaTabs/_SchemaTabs.scss +0 -4
  32. package/src/theme/styles.scss +4 -0
@@ -17,7 +17,7 @@ function create(tag, props) {
17
17
  }
18
18
  exports.create = create;
19
19
  function guard(value, cb) {
20
- if (!!value) {
20
+ if (!!value || value === 0) {
21
21
  const children = cb(value);
22
22
  return render(children);
23
23
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const utils_1 = require("./utils");
10
+ describe("guard", () => {
11
+ it("should guard empty strings", () => {
12
+ const actual = (0, utils_1.guard)("", (_) => {
13
+ throw new Error("Should not be called");
14
+ });
15
+ expect(actual).toBe("");
16
+ });
17
+ it("should guard undefined", () => {
18
+ const actual = (0, utils_1.guard)(undefined, (value) => {
19
+ throw new Error("Should not be called");
20
+ });
21
+ expect(actual).toBe("");
22
+ });
23
+ it("should guard false booleans", () => {
24
+ const actual = (0, utils_1.guard)(false, (value) => `${value}`);
25
+ expect(actual).toBe("");
26
+ });
27
+ it("should not guard strings", () => {
28
+ const actual = (0, utils_1.guard)("hello", (value) => value);
29
+ expect(actual).toBe("hello");
30
+ });
31
+ it("should not guard numbers", () => {
32
+ const actual = (0, utils_1.guard)(1, (value) => `${value}`);
33
+ expect(actual).toBe("1");
34
+ });
35
+ it("should not guard numbers equals to 0", () => {
36
+ const actual = (0, utils_1.guard)(0, (value) => `${value}`);
37
+ expect(actual).toBe("0");
38
+ });
39
+ it("should not guard true booleans", () => {
40
+ const actual = (0, utils_1.guard)(true, (value) => `${value}`);
41
+ expect(actual).toBe("true");
42
+ });
43
+ });
@@ -246,19 +246,14 @@ function CodeSnippets({ postman, codeSamples }) {
246
246
  return defaultLang[0] ?? mergedLangs[0];
247
247
  });
248
248
  const [codeText, setCodeText] = (0, react_1.useState)("");
249
- const [codeSampleCodeText, setCodeSampleCodeText] = (0, react_1.useState)("");
249
+ const [codeSampleCodeText, setCodeSampleCodeText] = (0, react_1.useState)(
250
+ () => (0, languages_1.getCodeSampleSourceFromLanguage)(language)
251
+ );
250
252
  (0, react_1.useEffect)(() => {
251
- // initial active language is custom code sample
252
- if (
253
- language &&
254
- language.sample &&
255
- language.samples &&
256
- language.samplesSources
257
- ) {
258
- const sampleIndex = language.samples.findIndex(
259
- (smp) => smp === language.sample
253
+ if (language && !!language.sample) {
254
+ setCodeSampleCodeText(
255
+ (0, languages_1.getCodeSampleSourceFromLanguage)(language)
260
256
  );
261
- setCodeSampleCodeText(language.samplesSources[sampleIndex]);
262
257
  }
263
258
  if (language && !!language.options) {
264
259
  const postmanRequest = (0, buildPostmanRequest_1.default)(postman, {
@@ -388,7 +383,9 @@ function CodeSnippets({ postman, codeSamples }) {
388
383
  action: {
389
384
  setLanguage: setLanguage,
390
385
  setSelectedVariant: setSelectedVariant,
386
+ setSelectedSample: setSelectedSample,
391
387
  },
388
+ languageSet: mergedLangs,
392
389
  lazy: true,
393
390
  },
394
391
  mergedLangs.map((lang) => {
@@ -414,6 +411,7 @@ function CodeSnippets({ postman, codeSamples }) {
414
411
  includeSample: true,
415
412
  currentLanguage: lang.language,
416
413
  defaultValue: selectedSample,
414
+ languageSet: mergedLangs,
417
415
  lazy: true,
418
416
  },
419
417
  lang.samples.map((sample, index) => {
@@ -452,6 +450,7 @@ function CodeSnippets({ postman, codeSamples }) {
452
450
  includeVariant: true,
453
451
  currentLanguage: lang.language,
454
452
  defaultValue: selectedVariant,
453
+ languageSet: mergedLangs,
455
454
  lazy: true,
456
455
  },
457
456
  lang.variants.map((variant, index) => {
@@ -1,2 +1,3 @@
1
1
  import { CodeSample, Language } from "./code-snippets-types";
2
2
  export declare function mergeCodeSampleLanguage(languages: Language[], codeSamples: CodeSample[]): Language[];
3
+ export declare function getCodeSampleSourceFromLanguage(language: Language): string;
@@ -6,7 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  * ========================================================================== */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.mergeCodeSampleLanguage = void 0;
9
+ exports.getCodeSampleSourceFromLanguage = exports.mergeCodeSampleLanguage =
10
+ void 0;
10
11
  function mergeCodeSampleLanguage(languages, codeSamples) {
11
12
  return languages.map((language) => {
12
13
  const languageCodeSamples = codeSamples.filter(
@@ -30,3 +31,18 @@ function mergeCodeSampleLanguage(languages, codeSamples) {
30
31
  });
31
32
  }
32
33
  exports.mergeCodeSampleLanguage = mergeCodeSampleLanguage;
34
+ function getCodeSampleSourceFromLanguage(language) {
35
+ if (
36
+ language &&
37
+ language.sample &&
38
+ language.samples &&
39
+ language.samplesSources
40
+ ) {
41
+ const sampleIndex = language.samples.findIndex(
42
+ (smp) => smp === language.sample
43
+ );
44
+ return language.samplesSources[sampleIndex];
45
+ }
46
+ return "";
47
+ }
48
+ exports.getCodeSampleSourceFromLanguage = getCodeSampleSourceFromLanguage;
@@ -6,9 +6,10 @@ export interface Props {
6
6
  [key: string]: React.Dispatch<any>;
7
7
  };
8
8
  currentLanguage: Language;
9
+ languageSet: Language[];
9
10
  includeVariant: boolean;
10
11
  }
11
- export interface TabListProps extends Props, TabProps {
12
+ export interface CodeTabsProps extends Props, TabProps {
12
13
  includeSample?: boolean;
13
14
  }
14
- export default function CodeTabs(props: TabProps & Props): React.JSX.Element;
15
+ export default function CodeTabs(props: CodeTabsProps & Props): React.JSX.Element;
@@ -58,11 +58,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
58
58
  const react_1 = __importStar(require("react"));
59
59
  const internal_1 = require("@docusaurus/theme-common/internal");
60
60
  const useIsBrowser_1 = __importDefault(require("@docusaurus/useIsBrowser"));
61
- const CodeSnippets_1 = require("@theme/ApiExplorer/CodeSnippets");
62
61
  const clsx_1 = __importDefault(require("clsx"));
63
62
  function TabList({
64
63
  action,
65
64
  currentLanguage,
65
+ languageSet,
66
66
  includeVariant,
67
67
  includeSample,
68
68
  className,
@@ -85,20 +85,23 @@ function TabList({
85
85
  if (action) {
86
86
  let newLanguage;
87
87
  if (currentLanguage && includeVariant) {
88
- newLanguage = CodeSnippets_1.languageSet.filter(
88
+ newLanguage = languageSet.filter(
89
89
  (lang) => lang.language === currentLanguage
90
90
  )[0];
91
91
  newLanguage.variant = newTabValue;
92
92
  action.setSelectedVariant(newTabValue.toLowerCase());
93
+ } else if (currentLanguage && includeSample) {
94
+ newLanguage = languageSet.filter(
95
+ (lang) => lang.language === currentLanguage
96
+ )[0];
97
+ newLanguage.sample = newTabValue;
98
+ action.setSelectedSample(newTabValue);
93
99
  } else {
94
- newLanguage = CodeSnippets_1.languageSet.filter(
100
+ newLanguage = languageSet.filter(
95
101
  (lang) => lang.language === newTabValue
96
102
  )[0];
97
103
  action.setSelectedVariant(newLanguage.variant.toLowerCase());
98
- }
99
- if (currentLanguage && includeSample) {
100
- newLanguage.sample = newTabValue;
101
- action.setSelectedSample(newTabValue.toLowerCase());
104
+ action.setSelectedSample(newLanguage.sample);
102
105
  }
103
106
  action.setLanguage(newLanguage);
104
107
  }
@@ -1,4 +1,4 @@
1
1
  /// <reference types="@docusaurus/plugin-content-docs" />
2
- import React from "react";
2
+ /// <reference types="react" />
3
3
  import type { Props } from "@theme/DocItem";
4
- export default function ApiItem(props: Props): React.JSX.Element;
4
+ export default function ApiItem(props: Props): JSX.Element;
@@ -41,6 +41,7 @@ function ApiItem(props) {
41
41
  const { frontMatter } = MDXComponent;
42
42
  const { info_path: infoPath } = frontMatter;
43
43
  let { api } = frontMatter;
44
+ const { schema } = frontMatter;
44
45
  // decompress and parse
45
46
  if (api) {
46
47
  api = JSON.parse(
@@ -164,6 +165,29 @@ function ApiItem(props) {
164
165
  )
165
166
  )
166
167
  );
168
+ } else if (schema) {
169
+ return react_1.default.createElement(
170
+ internal_1.DocProvider,
171
+ { content: props.content },
172
+ react_1.default.createElement(
173
+ theme_common_1.HtmlClassNameProvider,
174
+ { className: docHtmlClassName },
175
+ react_1.default.createElement(Metadata_1.default, null),
176
+ react_1.default.createElement(
177
+ Layout_1.default,
178
+ null,
179
+ react_1.default.createElement(
180
+ "div",
181
+ { className: (0, clsx_1.default)("row", "theme-api-markdown") },
182
+ react_1.default.createElement(
183
+ "div",
184
+ { className: "col col--12" },
185
+ react_1.default.createElement(MDXComponent, null)
186
+ )
187
+ )
188
+ )
189
+ )
190
+ );
167
191
  }
168
192
  // Non-API docs
169
193
  return react_1.default.createElement(
@@ -10,7 +10,9 @@
10
10
  }
11
11
 
12
12
  .openapi-tabs__response-header {
13
- margin-bottom: 0;
13
+ &.openapi-tabs__heading {
14
+ margin-bottom: 0;
15
+ }
14
16
  }
15
17
 
16
18
  .openapi-tabs__response-code-item {
@@ -131,7 +131,11 @@ function TabList({
131
131
  { className: "openapi-tabs__response-header-section" },
132
132
  react_1.default.createElement(
133
133
  Heading_1.default,
134
- { as: "h2", id: id, className: "openapi-tabs__response-header" },
134
+ {
135
+ as: "h2",
136
+ id: id,
137
+ className: "openapi-tabs__heading openapi-tabs__response-header",
138
+ },
135
139
  label
136
140
  ),
137
141
  react_1.default.createElement(
@@ -8,10 +8,13 @@
8
8
  .openapi-tabs__operation-container {
9
9
  display: flex;
10
10
  align-items: center;
11
- margin-top: 1rem;
12
11
  overflow: hidden;
13
12
  }
14
13
 
14
+ .openapi-tabs__operation-header {
15
+ margin-bottom: 0;
16
+ }
17
+
15
18
  .openapi-tabs__operation-item {
16
19
  display: flex;
17
20
  align-items: center;
@@ -15,8 +15,9 @@ export interface Props {
15
15
  examples: Map<ExampleObject>;
16
16
  name: string;
17
17
  required: boolean;
18
+ deprecated: boolean;
18
19
  schema: any;
19
20
  };
20
21
  }
21
- declare function ParamsItem({ param: { description, example, examples, name, required, schema }, }: Props): React.JSX.Element;
22
+ declare function ParamsItem({ param: { description, example, examples, name, required, schema, deprecated }, }: Props): React.JSX.Element;
22
23
  export default ParamsItem;
@@ -15,13 +15,15 @@ const react_1 = __importDefault(require("react"));
15
15
  const CodeBlock_1 = __importDefault(require("@theme/CodeBlock"));
16
16
  const SchemaTabs_1 = __importDefault(require("@theme/SchemaTabs"));
17
17
  const TabItem_1 = __importDefault(require("@theme/TabItem"));
18
+ /* eslint-disable import/no-extraneous-dependencies*/
19
+ const clsx_1 = __importDefault(require("clsx"));
18
20
  const react_markdown_1 = __importDefault(require("react-markdown"));
19
21
  const rehype_raw_1 = __importDefault(require("rehype-raw"));
20
22
  const createDescription_1 = require("../../markdown/createDescription");
21
23
  const schema_1 = require("../../markdown/schema");
22
24
  const utils_1 = require("../../markdown/utils");
23
25
  function ParamsItem({
24
- param: { description, example, examples, name, required, schema },
26
+ param: { description, example, examples, name, required, schema, deprecated },
25
27
  }) {
26
28
  if (!schema || !schema?.type) {
27
29
  schema = { type: "any" };
@@ -41,6 +43,13 @@ function ParamsItem({
41
43
  "required"
42
44
  )
43
45
  );
46
+ const renderDeprecated = (0, utils_1.guard)(deprecated, () =>
47
+ react_1.default.createElement(
48
+ "span",
49
+ { className: "openapi-schema__deprecated" },
50
+ "deprecated"
51
+ )
52
+ );
44
53
  const renderSchema = (0, utils_1.guard)(
45
54
  (0, schema_1.getQualifierMessage)(schema),
46
55
  (message) =>
@@ -161,15 +170,20 @@ function ParamsItem({
161
170
  { className: "openapi-schema__container" },
162
171
  react_1.default.createElement(
163
172
  "strong",
164
- { className: "openapi-schema__property" },
173
+ {
174
+ className: (0, clsx_1.default)("openapi-schema__property", {
175
+ "openapi-schema__strikethrough": deprecated,
176
+ }),
177
+ },
165
178
  name
166
179
  ),
167
180
  renderSchemaName,
168
- required &&
181
+ (required || deprecated) &&
169
182
  react_1.default.createElement("span", {
170
183
  className: "openapi-schema__divider",
171
184
  }),
172
- renderSchemaRequired
185
+ renderSchemaRequired,
186
+ renderDeprecated
173
187
  ),
174
188
  renderSchema,
175
189
  renderDefaultValue,
@@ -103,16 +103,14 @@ function SchemaItem({
103
103
  })
104
104
  )
105
105
  );
106
- const renderDefaultValue = (0, utils_1.guard)(
107
- typeof defaultValue === "boolean" ? defaultValue.toString() : defaultValue,
108
- (value) =>
109
- react_1.default.createElement(
110
- "div",
111
- { className: "" },
112
- react_1.default.createElement(react_markdown_1.default, {
113
- children: `**Default value:** \`${value}\``,
114
- })
115
- )
106
+ const renderDefaultValue = (0, utils_1.guard)(defaultValue, (value) =>
107
+ react_1.default.createElement(
108
+ "div",
109
+ { className: "" },
110
+ react_1.default.createElement(react_markdown_1.default, {
111
+ children: `**Default value:** \`${value}\``,
112
+ })
113
+ )
116
114
  );
117
115
  const schemaContent = react_1.default.createElement(
118
116
  "div",
@@ -140,7 +138,7 @@ function SchemaItem({
140
138
  className: "openapi-schema__divider",
141
139
  }),
142
140
  renderNullable,
143
- !deprecated && renderRequired,
141
+ renderRequired,
144
142
  renderDeprecated
145
143
  ),
146
144
  renderQualifierMessage,
@@ -5,10 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- .openapi-tabs__schema-container {
9
- margin-top: 1rem;
10
- }
11
-
12
8
  .openapi-tabs__schema-item {
13
9
  display: flex;
14
10
  align-items: center;
@@ -159,3 +159,7 @@
159
159
  .openapi-left-panel__container {
160
160
  border-right: thin solid var(--ifm-toc-border-color);
161
161
  }
162
+
163
+ .openapi-tabs__heading {
164
+ margin-bottom: 1rem;
165
+ }
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": "3.0.0-beta.5",
4
+ "version": "3.0.0-beta.7",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -44,7 +44,7 @@
44
44
  "clsx": "^1.1.1",
45
45
  "copy-text-to-clipboard": "^3.1.0",
46
46
  "crypto-js": "^4.1.1",
47
- "docusaurus-plugin-openapi-docs": "^3.0.0-beta.5",
47
+ "docusaurus-plugin-openapi-docs": "^3.0.0-beta.7",
48
48
  "docusaurus-plugin-sass": "^0.2.3",
49
49
  "file-saver": "^2.0.5",
50
50
  "lodash": "^4.17.20",
@@ -69,5 +69,5 @@
69
69
  "engines": {
70
70
  "node": ">=14"
71
71
  },
72
- "gitHead": "1f9c9fa811c1e9d42f3c3740a8f7407e3659d629"
72
+ "gitHead": "effd6b9afc0c416618002189e3823dcfc4356f30"
73
73
  }
@@ -0,0 +1,49 @@
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 { guard } from "./utils";
9
+
10
+ describe("guard", () => {
11
+ it("should guard empty strings", () => {
12
+ const actual = guard("", (_) => {
13
+ throw new Error("Should not be called");
14
+ });
15
+ expect(actual).toBe("");
16
+ });
17
+
18
+ it("should guard undefined", () => {
19
+ const actual = guard(undefined, (value) => {
20
+ throw new Error("Should not be called");
21
+ });
22
+ expect(actual).toBe("");
23
+ });
24
+
25
+ it("should guard false booleans", () => {
26
+ const actual = guard(false, (value) => `${value}`);
27
+ expect(actual).toBe("");
28
+ });
29
+
30
+ it("should not guard strings", () => {
31
+ const actual = guard("hello", (value) => value);
32
+ expect(actual).toBe("hello");
33
+ });
34
+
35
+ it("should not guard numbers", () => {
36
+ const actual = guard(1, (value) => `${value}`);
37
+ expect(actual).toBe("1");
38
+ });
39
+
40
+ it("should not guard numbers equals to 0", () => {
41
+ const actual = guard(0, (value) => `${value}`);
42
+ expect(actual).toBe("0");
43
+ });
44
+
45
+ it("should not guard true booleans", () => {
46
+ const actual = guard(true, (value) => `${value}`);
47
+ expect(actual).toBe("true");
48
+ });
49
+ });
@@ -26,7 +26,7 @@ export function guard<T>(
26
26
  value: T | undefined | string,
27
27
  cb: (value: T) => Children
28
28
  ): string {
29
- if (!!value) {
29
+ if (!!value || value === 0) {
30
30
  const children = cb(value as T);
31
31
  return render(children);
32
32
  }
@@ -17,7 +17,10 @@ import { useTypedSelector } from "@theme/ApiItem/hooks";
17
17
  import merge from "lodash/merge";
18
18
 
19
19
  import { CodeSample, Language } from "./code-snippets-types";
20
- import { mergeCodeSampleLanguage } from "./languages";
20
+ import {
21
+ getCodeSampleSourceFromLanguage,
22
+ mergeCodeSampleLanguage,
23
+ } from "./languages";
21
24
 
22
25
  export const languageSet: Language[] = [
23
26
  {
@@ -198,20 +201,13 @@ function CodeSnippets({ postman, codeSamples }: Props) {
198
201
  return defaultLang[0] ?? mergedLangs[0];
199
202
  });
200
203
  const [codeText, setCodeText] = useState<string>("");
201
- const [codeSampleCodeText, setCodeSampleCodeText] = useState<string>("");
204
+ const [codeSampleCodeText, setCodeSampleCodeText] = useState<
205
+ string | (() => string)
206
+ >(() => getCodeSampleSourceFromLanguage(language));
202
207
 
203
208
  useEffect(() => {
204
- // initial active language is custom code sample
205
- if (
206
- language &&
207
- language.sample &&
208
- language.samples &&
209
- language.samplesSources
210
- ) {
211
- const sampleIndex = language.samples.findIndex(
212
- (smp) => smp === language.sample
213
- );
214
- setCodeSampleCodeText(language.samplesSources[sampleIndex]);
209
+ if (language && !!language.sample) {
210
+ setCodeSampleCodeText(getCodeSampleSourceFromLanguage(language));
215
211
  }
216
212
 
217
213
  if (language && !!language.options) {
@@ -344,7 +340,9 @@ function CodeSnippets({ postman, codeSamples }: Props) {
344
340
  action={{
345
341
  setLanguage: setLanguage,
346
342
  setSelectedVariant: setSelectedVariant,
343
+ setSelectedSample: setSelectedSample,
347
344
  }}
345
+ languageSet={mergedLangs}
348
346
  lazy
349
347
  >
350
348
  {mergedLangs.map((lang) => {
@@ -367,6 +365,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
367
365
  includeSample={true}
368
366
  currentLanguage={lang.language}
369
367
  defaultValue={selectedSample}
368
+ languageSet={mergedLangs}
370
369
  lazy
371
370
  >
372
371
  {lang.samples.map((sample, index) => {
@@ -406,6 +405,7 @@ function CodeSnippets({ postman, codeSamples }: Props) {
406
405
  includeVariant={true}
407
406
  currentLanguage={lang.language}
408
407
  defaultValue={selectedVariant}
408
+ languageSet={mergedLangs}
409
409
  lazy
410
410
  >
411
411
  {lang.variants.map((variant, index) => {
@@ -35,3 +35,19 @@ export function mergeCodeSampleLanguage(
35
35
  return language;
36
36
  });
37
37
  }
38
+
39
+ export function getCodeSampleSourceFromLanguage(language: Language) {
40
+ if (
41
+ language &&
42
+ language.sample &&
43
+ language.samples &&
44
+ language.samplesSources
45
+ ) {
46
+ const sampleIndex = language.samples.findIndex(
47
+ (smp) => smp === language.sample
48
+ );
49
+ return language.samplesSources[sampleIndex];
50
+ }
51
+
52
+ return "";
53
+ }
@@ -15,7 +15,7 @@ import {
15
15
  } from "@docusaurus/theme-common/internal";
16
16
  import { TabItemProps } from "@docusaurus/theme-common/lib/utils/tabsUtils";
17
17
  import useIsBrowser from "@docusaurus/useIsBrowser";
18
- import { Language, languageSet } from "@theme/ApiExplorer/CodeSnippets";
18
+ import { Language } from "@theme/ApiExplorer/CodeSnippets";
19
19
  import clsx from "clsx";
20
20
 
21
21
  export interface Props {
@@ -23,16 +23,18 @@ export interface Props {
23
23
  [key: string]: React.Dispatch<any>;
24
24
  };
25
25
  currentLanguage: Language;
26
+ languageSet: Language[];
26
27
  includeVariant: boolean;
27
28
  }
28
29
 
29
- export interface TabListProps extends Props, TabProps {
30
+ export interface CodeTabsProps extends Props, TabProps {
30
31
  includeSample?: boolean;
31
32
  }
32
33
 
33
34
  function TabList({
34
35
  action,
35
36
  currentLanguage,
37
+ languageSet,
36
38
  includeVariant,
37
39
  includeSample,
38
40
  className,
@@ -40,7 +42,7 @@ function TabList({
40
42
  selectedValue,
41
43
  selectValue,
42
44
  tabValues,
43
- }: TabListProps & ReturnType<typeof useTabs>) {
45
+ }: CodeTabsProps & ReturnType<typeof useTabs>) {
44
46
  const tabRefs: (HTMLLIElement | null)[] = [];
45
47
  const { blockElementScrollPositionUntilNextRender } =
46
48
  useScrollPositionBlocker();
@@ -68,15 +70,18 @@ function TabList({
68
70
  )[0];
69
71
  newLanguage.variant = newTabValue;
70
72
  action.setSelectedVariant(newTabValue.toLowerCase());
73
+ } else if (currentLanguage && includeSample) {
74
+ newLanguage = languageSet.filter(
75
+ (lang: Language) => lang.language === currentLanguage
76
+ )[0];
77
+ newLanguage.sample = newTabValue;
78
+ action.setSelectedSample(newTabValue);
71
79
  } else {
72
80
  newLanguage = languageSet.filter(
73
81
  (lang: Language) => lang.language === newTabValue
74
82
  )[0];
75
83
  action.setSelectedVariant(newLanguage.variant.toLowerCase());
76
- }
77
- if (currentLanguage && includeSample) {
78
- newLanguage.sample = newTabValue;
79
- action.setSelectedSample(newTabValue.toLowerCase());
84
+ action.setSelectedSample(newLanguage.sample);
80
85
  }
81
86
  action.setLanguage(newLanguage);
82
87
  }
@@ -151,7 +156,7 @@ function TabContent({
151
156
  lazy,
152
157
  children,
153
158
  selectedValue,
154
- }: TabProps & ReturnType<typeof useTabs>): React.JSX.Element | null {
159
+ }: CodeTabsProps & ReturnType<typeof useTabs>): React.JSX.Element | null {
155
160
  const childTabs = (Array.isArray(children) ? children : [children]).filter(
156
161
  Boolean
157
162
  ) as ReactElement<TabItemProps>[];
@@ -177,7 +182,7 @@ function TabContent({
177
182
  );
178
183
  }
179
184
 
180
- function TabsComponent(props: TabProps & Props): React.JSX.Element {
185
+ function TabsComponent(props: CodeTabsProps & Props): React.JSX.Element {
181
186
  const tabs = useTabs(props);
182
187
  const { className } = props;
183
188
 
@@ -191,7 +196,9 @@ function TabsComponent(props: TabProps & Props): React.JSX.Element {
191
196
  );
192
197
  }
193
198
 
194
- export default function CodeTabs(props: TabProps & Props): React.JSX.Element {
199
+ export default function CodeTabs(
200
+ props: CodeTabsProps & Props
201
+ ): React.JSX.Element {
195
202
  const isBrowser = useIsBrowser();
196
203
  return (
197
204
  <TabsComponent
@@ -42,13 +42,18 @@ interface ApiFrontMatter extends DocFrontMatter {
42
42
  readonly api?: ApiItemType;
43
43
  }
44
44
 
45
+ interface SchemaFrontMatter extends DocFrontMatter {
46
+ readonly schema?: boolean;
47
+ }
48
+
45
49
  // @ts-ignore
46
- export default function ApiItem(props: Props): React.JSX.Element {
50
+ export default function ApiItem(props: Props): JSX.Element {
47
51
  const docHtmlClassName = `docs-doc-id-${props.content.metadata.id}`;
48
52
  const MDXComponent = props.content;
49
53
  const { frontMatter } = MDXComponent;
50
54
  const { info_path: infoPath } = frontMatter as DocFrontMatter;
51
55
  let { api } = frontMatter as ApiFrontMatter;
56
+ const { schema } = frontMatter as SchemaFrontMatter;
52
57
  // decompress and parse
53
58
  if (api) {
54
59
  api = JSON.parse(
@@ -158,6 +163,21 @@ export default function ApiItem(props: Props): React.JSX.Element {
158
163
  </HtmlClassNameProvider>
159
164
  </DocProvider>
160
165
  );
166
+ } else if (schema) {
167
+ return (
168
+ <DocProvider content={props.content}>
169
+ <HtmlClassNameProvider className={docHtmlClassName}>
170
+ <DocItemMetadata />
171
+ <DocItemLayout>
172
+ <div className={clsx("row", "theme-api-markdown")}>
173
+ <div className="col col--12">
174
+ <MDXComponent />
175
+ </div>
176
+ </div>
177
+ </DocItemLayout>
178
+ </HtmlClassNameProvider>
179
+ </DocProvider>
180
+ );
161
181
  }
162
182
 
163
183
  // Non-API docs
@@ -10,7 +10,9 @@
10
10
  }
11
11
 
12
12
  .openapi-tabs__response-header {
13
- margin-bottom: 0;
13
+ &.openapi-tabs__heading {
14
+ margin-bottom: 0;
15
+ }
14
16
  }
15
17
 
16
18
  .openapi-tabs__response-code-item {
@@ -114,7 +114,11 @@ function TabList({
114
114
 
115
115
  return (
116
116
  <div className="openapi-tabs__response-header-section">
117
- <Heading as="h2" id={id} className="openapi-tabs__response-header">
117
+ <Heading
118
+ as="h2"
119
+ id={id}
120
+ className="openapi-tabs__heading openapi-tabs__response-header"
121
+ >
118
122
  {label}
119
123
  </Heading>
120
124
  <div className="openapi-tabs__response-container">
@@ -8,10 +8,13 @@
8
8
  .openapi-tabs__operation-container {
9
9
  display: flex;
10
10
  align-items: center;
11
- margin-top: 1rem;
12
11
  overflow: hidden;
13
12
  }
14
13
 
14
+ .openapi-tabs__operation-header {
15
+ margin-bottom: 0;
16
+ }
17
+
15
18
  .openapi-tabs__operation-item {
16
19
  display: flex;
17
20
  align-items: center;
@@ -10,6 +10,8 @@ import React from "react";
10
10
  import CodeBlock from "@theme/CodeBlock";
11
11
  import SchemaTabs from "@theme/SchemaTabs";
12
12
  import TabItem from "@theme/TabItem";
13
+ /* eslint-disable import/no-extraneous-dependencies*/
14
+ import clsx from "clsx";
13
15
  import ReactMarkdown from "react-markdown";
14
16
  import rehypeRaw from "rehype-raw";
15
17
 
@@ -35,12 +37,13 @@ export interface Props {
35
37
  examples: Map<ExampleObject>;
36
38
  name: string;
37
39
  required: boolean;
40
+ deprecated: boolean;
38
41
  schema: any;
39
42
  };
40
43
  }
41
44
 
42
45
  function ParamsItem({
43
- param: { description, example, examples, name, required, schema },
46
+ param: { description, example, examples, name, required, schema, deprecated },
44
47
  }: Props) {
45
48
  if (!schema || !schema?.type) {
46
49
  schema = { type: "any" };
@@ -54,6 +57,10 @@ function ParamsItem({
54
57
  <span className="openapi-schema__required">required</span>
55
58
  ));
56
59
 
60
+ const renderDeprecated = guard(deprecated, () => (
61
+ <span className="openapi-schema__deprecated">deprecated</span>
62
+ ));
63
+
57
64
  const renderSchema = guard(getQualifierMessage(schema), (message) => (
58
65
  <div>
59
66
  <ReactMarkdown
@@ -134,10 +141,19 @@ function ParamsItem({
134
141
  return (
135
142
  <div className="openapi-params__list-item">
136
143
  <span className="openapi-schema__container">
137
- <strong className="openapi-schema__property">{name}</strong>
144
+ <strong
145
+ className={clsx("openapi-schema__property", {
146
+ "openapi-schema__strikethrough": deprecated,
147
+ })}
148
+ >
149
+ {name}
150
+ </strong>
138
151
  {renderSchemaName}
139
- {required && <span className="openapi-schema__divider"></span>}
152
+ {(required || deprecated) && (
153
+ <span className="openapi-schema__divider"></span>
154
+ )}
140
155
  {renderSchemaRequired}
156
+ {renderDeprecated}
141
157
  </span>
142
158
  {renderSchema}
143
159
  {renderDefaultValue}
@@ -90,14 +90,11 @@ export default function SchemaItem({
90
90
  </div>
91
91
  ));
92
92
 
93
- const renderDefaultValue = guard(
94
- typeof defaultValue === "boolean" ? defaultValue.toString() : defaultValue,
95
- (value) => (
96
- <div className="">
97
- <ReactMarkdown children={`**Default value:** \`${value}\``} />
98
- </div>
99
- )
100
- );
93
+ const renderDefaultValue = guard(defaultValue, (value) => (
94
+ <div className="">
95
+ <ReactMarkdown children={`**Default value:** \`${value}\``} />
96
+ </div>
97
+ ));
101
98
 
102
99
  const schemaContent = (
103
100
  <div>
@@ -114,7 +111,7 @@ export default function SchemaItem({
114
111
  <span className="openapi-schema__divider"></span>
115
112
  )}
116
113
  {renderNullable}
117
- {!deprecated && renderRequired}
114
+ {renderRequired}
118
115
  {renderDeprecated}
119
116
  </span>
120
117
  {renderQualifierMessage}
@@ -5,10 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- .openapi-tabs__schema-container {
9
- margin-top: 1rem;
10
- }
11
-
12
8
  .openapi-tabs__schema-item {
13
9
  display: flex;
14
10
  align-items: center;
@@ -159,3 +159,7 @@
159
159
  .openapi-left-panel__container {
160
160
  border-right: thin solid var(--ifm-toc-border-color);
161
161
  }
162
+
163
+ .openapi-tabs__heading {
164
+ margin-bottom: 1rem;
165
+ }