@gitbook/react-openapi 1.4.3 → 1.5.2

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 (263) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/InteractiveSection.js +59 -0
  3. package/dist/Markdown.js +10 -0
  4. package/dist/OpenAPICodeSample.js +219 -0
  5. package/dist/OpenAPICodeSampleInteractive.js +66 -0
  6. package/dist/OpenAPICodeSampleSelector.js +45 -0
  7. package/dist/OpenAPICopyButton.js +39 -0
  8. package/dist/OpenAPIDisclosure.js +30 -0
  9. package/dist/OpenAPIDisclosureGroup.js +75 -0
  10. package/dist/OpenAPIExample.js +41 -0
  11. package/dist/OpenAPIMediaType.js +58 -0
  12. package/dist/OpenAPIOperation.d.ts +12 -7
  13. package/dist/OpenAPIOperation.js +30 -0
  14. package/dist/OpenAPIOperationContext.d.ts +10 -6
  15. package/dist/OpenAPIOperationContext.js +30 -0
  16. package/dist/OpenAPIPath.js +51 -0
  17. package/dist/OpenAPIPrefillContextProvider.d.ts +11 -7
  18. package/dist/OpenAPIPrefillContextProvider.js +25 -0
  19. package/dist/OpenAPIRequestBody.js +28 -0
  20. package/dist/OpenAPIRequestBodyHeaderType.js +23 -0
  21. package/dist/OpenAPIResponse.js +39 -0
  22. package/dist/OpenAPIResponseExample.js +75 -0
  23. package/dist/OpenAPIResponseExampleContent.js +61 -0
  24. package/dist/OpenAPIResponses.js +61 -0
  25. package/dist/OpenAPISchema.js +373 -0
  26. package/dist/OpenAPISchemaName.js +45 -0
  27. package/dist/OpenAPISchemaServer.js +13 -0
  28. package/dist/OpenAPISecurities.js +124 -0
  29. package/dist/OpenAPISelect.js +45 -0
  30. package/dist/OpenAPISpec.js +73 -0
  31. package/dist/OpenAPIWebhook.d.ts +12 -7
  32. package/dist/OpenAPIWebhook.js +28 -0
  33. package/dist/OpenAPIWebhookExample.js +40 -0
  34. package/dist/ScalarApiButton.js +87 -0
  35. package/dist/StaticSection.js +37 -0
  36. package/dist/code-samples.js +267 -419
  37. package/dist/common/OpenAPIColumnSpec.js +23 -0
  38. package/dist/common/OpenAPIOperationDescription.js +18 -0
  39. package/dist/common/OpenAPIStability.js +17 -0
  40. package/dist/common/OpenAPISummary.js +27 -0
  41. package/dist/contentTypeChecks.js +24 -20
  42. package/dist/context.d.ts +68 -72
  43. package/dist/context.js +25 -39
  44. package/dist/decycle.js +39 -68
  45. package/dist/dereference.js +20 -64
  46. package/dist/generateSchemaExample.js +188 -332
  47. package/dist/getDisclosureLabel.js +15 -16
  48. package/dist/getOrCreateStoreByKey.js +20 -17
  49. package/dist/index.d.ts +12 -10
  50. package/dist/index.js +11 -8
  51. package/dist/json2xml.js +10 -5
  52. package/dist/resolveOpenAPIOperation.d.ts +11 -7
  53. package/dist/resolveOpenAPIOperation.js +88 -159
  54. package/dist/resolveOpenAPIWebhook.d.ts +11 -7
  55. package/dist/resolveOpenAPIWebhook.js +41 -116
  56. package/dist/schemas/OpenAPISchemaItem.js +26 -0
  57. package/dist/schemas/OpenAPISchemas.d.ts +16 -11
  58. package/dist/schemas/OpenAPISchemas.js +57 -0
  59. package/dist/schemas/resolveOpenAPISchemas.d.ts +9 -4
  60. package/dist/schemas/resolveOpenAPISchemas.js +15 -59
  61. package/dist/stringifyOpenAPI.js +12 -13
  62. package/dist/translate.js +43 -0
  63. package/dist/translations/de.js +47 -42
  64. package/dist/translations/en.d.ts +46 -42
  65. package/dist/translations/en.js +47 -42
  66. package/dist/translations/es.js +47 -42
  67. package/dist/translations/fr.js +47 -42
  68. package/dist/translations/index.d.ts +404 -391
  69. package/dist/translations/index.js +28 -24
  70. package/dist/translations/ja.js +47 -42
  71. package/dist/translations/nl.js +47 -42
  72. package/dist/translations/no.js +47 -42
  73. package/dist/translations/pt-br.js +47 -42
  74. package/dist/translations/types.d.ts +7 -5
  75. package/dist/translations/zh.js +47 -42
  76. package/dist/types.d.ts +30 -24
  77. package/dist/util/example.js +84 -0
  78. package/dist/util/server.js +32 -38
  79. package/dist/util/tryit-prefill.js +135 -121
  80. package/dist/utils.js +135 -196
  81. package/package.json +18 -11
  82. package/dist/InteractiveSection.d.ts +0 -33
  83. package/dist/InteractiveSection.jsx +0 -61
  84. package/dist/Markdown.d.ts +0 -4
  85. package/dist/Markdown.jsx +0 -5
  86. package/dist/OpenAPICodeSample.d.ts +0 -19
  87. package/dist/OpenAPICodeSample.jsx +0 -230
  88. package/dist/OpenAPICodeSampleInteractive.d.ts +0 -14
  89. package/dist/OpenAPICodeSampleInteractive.jsx +0 -73
  90. package/dist/OpenAPICodeSampleSelector.d.ts +0 -14
  91. package/dist/OpenAPICodeSampleSelector.jsx +0 -44
  92. package/dist/OpenAPICopyButton.d.ts +0 -13
  93. package/dist/OpenAPICopyButton.jsx +0 -35
  94. package/dist/OpenAPIDisclosure.d.ts +0 -11
  95. package/dist/OpenAPIDisclosure.jsx +0 -30
  96. package/dist/OpenAPIDisclosureGroup.d.ts +0 -23
  97. package/dist/OpenAPIDisclosureGroup.jsx +0 -83
  98. package/dist/OpenAPIExample.d.ts +0 -16
  99. package/dist/OpenAPIExample.jsx +0 -36
  100. package/dist/OpenAPIMediaType.d.ts +0 -21
  101. package/dist/OpenAPIMediaType.jsx +0 -61
  102. package/dist/OpenAPIOperation.jsx +0 -25
  103. package/dist/OpenAPIOperationContext.jsx +0 -26
  104. package/dist/OpenAPIOperationDescription.d.ts +0 -9
  105. package/dist/OpenAPIOperationDescription.jsx +0 -22
  106. package/dist/OpenAPIOperationStability.d.ts +0 -9
  107. package/dist/OpenAPIOperationStability.jsx +0 -27
  108. package/dist/OpenAPIPath.d.ts +0 -18
  109. package/dist/OpenAPIPath.jsx +0 -55
  110. package/dist/OpenAPIPrefillContextProvider.jsx +0 -19
  111. package/dist/OpenAPIRequestBody.d.ts +0 -11
  112. package/dist/OpenAPIRequestBody.jsx +0 -28
  113. package/dist/OpenAPIRequestBodyHeaderType.d.ts +0 -8
  114. package/dist/OpenAPIRequestBodyHeaderType.jsx +0 -25
  115. package/dist/OpenAPIResponse.d.ts +0 -10
  116. package/dist/OpenAPIResponse.jsx +0 -57
  117. package/dist/OpenAPIResponseExample.d.ts +0 -9
  118. package/dist/OpenAPIResponseExample.jsx +0 -105
  119. package/dist/OpenAPIResponseExampleContent.d.ts +0 -22
  120. package/dist/OpenAPIResponseExampleContent.jsx +0 -60
  121. package/dist/OpenAPIResponses.d.ts +0 -9
  122. package/dist/OpenAPIResponses.jsx +0 -77
  123. package/dist/OpenAPISchema.d.ts +0 -27
  124. package/dist/OpenAPISchema.jsx +0 -400
  125. package/dist/OpenAPISchemaName.d.ts +0 -16
  126. package/dist/OpenAPISchemaName.jsx +0 -43
  127. package/dist/OpenAPISchemaServer.d.ts +0 -12
  128. package/dist/OpenAPISchemaServer.jsx +0 -8
  129. package/dist/OpenAPISecurities.d.ts +0 -9
  130. package/dist/OpenAPISecurities.jsx +0 -114
  131. package/dist/OpenAPISelect.d.ts +0 -22
  132. package/dist/OpenAPISelect.jsx +0 -44
  133. package/dist/OpenAPISpec.d.ts +0 -6
  134. package/dist/OpenAPISpec.jsx +0 -80
  135. package/dist/OpenAPITabs.d.ts +0 -26
  136. package/dist/OpenAPITabs.jsx +0 -109
  137. package/dist/OpenAPIWebhook.jsx +0 -23
  138. package/dist/OpenAPIWebhookExample.d.ts +0 -6
  139. package/dist/OpenAPIWebhookExample.jsx +0 -41
  140. package/dist/ScalarApiButton.d.ts +0 -14
  141. package/dist/ScalarApiButton.jsx +0 -81
  142. package/dist/StaticSection.d.ts +0 -13
  143. package/dist/StaticSection.jsx +0 -32
  144. package/dist/code-samples.d.ts +0 -17
  145. package/dist/common/OpenAPIColumnSpec.d.ts +0 -6
  146. package/dist/common/OpenAPIColumnSpec.jsx +0 -20
  147. package/dist/common/OpenAPIOperationDescription.d.ts +0 -6
  148. package/dist/common/OpenAPIOperationDescription.jsx +0 -19
  149. package/dist/common/OpenAPIStability.d.ts +0 -4
  150. package/dist/common/OpenAPIStability.jsx +0 -15
  151. package/dist/common/OpenAPISummary.d.ts +0 -6
  152. package/dist/common/OpenAPISummary.jsx +0 -30
  153. package/dist/contentTypeChecks.d.ts +0 -10
  154. package/dist/decycle.d.ts +0 -2
  155. package/dist/dereference.d.ts +0 -5
  156. package/dist/generateSchemaExample.d.ts +0 -45
  157. package/dist/getDisclosureLabel.d.ts +0 -7
  158. package/dist/getOrCreateStoreByKey.d.ts +0 -10
  159. package/dist/json2xml.d.ts +0 -4
  160. package/dist/schemas/OpenAPISchemaItem.d.ts +0 -7
  161. package/dist/schemas/OpenAPISchemaItem.jsx +0 -16
  162. package/dist/schemas/OpenAPISchemas.jsx +0 -59
  163. package/dist/schemas/index.d.ts +0 -2
  164. package/dist/schemas/index.js +0 -2
  165. package/dist/stringifyOpenAPI.d.ts +0 -4
  166. package/dist/translate.d.ts +0 -10
  167. package/dist/translate.jsx +0 -75
  168. package/dist/translations/de.d.ts +0 -43
  169. package/dist/translations/es.d.ts +0 -43
  170. package/dist/translations/fr.d.ts +0 -43
  171. package/dist/translations/ja.d.ts +0 -43
  172. package/dist/translations/nl.d.ts +0 -43
  173. package/dist/translations/no.d.ts +0 -43
  174. package/dist/translations/pt-br.d.ts +0 -43
  175. package/dist/translations/types.js +0 -1
  176. package/dist/translations/zh.d.ts +0 -43
  177. package/dist/tsconfig.build.tsbuildinfo +0 -1
  178. package/dist/types.js +0 -1
  179. package/dist/util/example.d.ts +0 -35
  180. package/dist/util/example.jsx +0 -103
  181. package/dist/util/server.d.ts +0 -9
  182. package/dist/util/tryit-prefill.d.ts +0 -20
  183. package/dist/utils.d.ts +0 -50
  184. package/src/InteractiveSection.tsx +0 -147
  185. package/src/Markdown.tsx +0 -12
  186. package/src/OpenAPICodeSample.tsx +0 -330
  187. package/src/OpenAPICodeSampleInteractive.tsx +0 -136
  188. package/src/OpenAPICodeSampleSelector.tsx +0 -94
  189. package/src/OpenAPICopyButton.tsx +0 -72
  190. package/src/OpenAPIDisclosure.tsx +0 -46
  191. package/src/OpenAPIDisclosureGroup.tsx +0 -158
  192. package/src/OpenAPIExample.tsx +0 -55
  193. package/src/OpenAPIMediaType.tsx +0 -139
  194. package/src/OpenAPIOperation.tsx +0 -35
  195. package/src/OpenAPIOperationContext.tsx +0 -45
  196. package/src/OpenAPIOperationDescription.tsx +0 -34
  197. package/src/OpenAPIOperationStability.tsx +0 -39
  198. package/src/OpenAPIPath.tsx +0 -90
  199. package/src/OpenAPIPrefillContextProvider.tsx +0 -40
  200. package/src/OpenAPIRequestBody.tsx +0 -54
  201. package/src/OpenAPIRequestBodyHeaderType.tsx +0 -36
  202. package/src/OpenAPIResponse.tsx +0 -82
  203. package/src/OpenAPIResponseExample.tsx +0 -151
  204. package/src/OpenAPIResponseExampleContent.tsx +0 -125
  205. package/src/OpenAPIResponses.tsx +0 -125
  206. package/src/OpenAPISchema.test.ts +0 -172
  207. package/src/OpenAPISchema.tsx +0 -654
  208. package/src/OpenAPISchemaName.tsx +0 -80
  209. package/src/OpenAPISchemaServer.tsx +0 -34
  210. package/src/OpenAPISecurities.tsx +0 -231
  211. package/src/OpenAPISelect.tsx +0 -96
  212. package/src/OpenAPISpec.tsx +0 -138
  213. package/src/OpenAPITabs.tsx +0 -147
  214. package/src/OpenAPIWebhook.tsx +0 -33
  215. package/src/OpenAPIWebhookExample.tsx +0 -60
  216. package/src/ScalarApiButton.tsx +0 -132
  217. package/src/StaticSection.tsx +0 -91
  218. package/src/__snapshots__/json2xml.test.ts.snap +0 -18
  219. package/src/code-samples.test.ts +0 -714
  220. package/src/code-samples.ts +0 -448
  221. package/src/common/OpenAPIColumnSpec.tsx +0 -31
  222. package/src/common/OpenAPIOperationDescription.tsx +0 -31
  223. package/src/common/OpenAPIStability.tsx +0 -23
  224. package/src/common/OpenAPISummary.tsx +0 -45
  225. package/src/contentTypeChecks.ts +0 -39
  226. package/src/context.ts +0 -99
  227. package/src/decycle.ts +0 -68
  228. package/src/dereference.ts +0 -29
  229. package/src/generateSchemaExample.test.ts +0 -1040
  230. package/src/generateSchemaExample.ts +0 -530
  231. package/src/getDisclosureLabel.ts +0 -25
  232. package/src/getOrCreateStoreByKey.ts +0 -33
  233. package/src/index.ts +0 -10
  234. package/src/json2xml.test.ts +0 -46
  235. package/src/json2xml.ts +0 -8
  236. package/src/resolveOpenAPIOperation.test.ts +0 -177
  237. package/src/resolveOpenAPIOperation.ts +0 -151
  238. package/src/resolveOpenAPIWebhook.ts +0 -99
  239. package/src/schemas/OpenAPISchemaItem.tsx +0 -34
  240. package/src/schemas/OpenAPISchemas.tsx +0 -98
  241. package/src/schemas/index.ts +0 -2
  242. package/src/schemas/resolveOpenAPISchemas.test.ts +0 -174
  243. package/src/schemas/resolveOpenAPISchemas.ts +0 -28
  244. package/src/stringifyOpenAPI.ts +0 -25
  245. package/src/translate.tsx +0 -80
  246. package/src/translations/de.ts +0 -43
  247. package/src/translations/en.ts +0 -43
  248. package/src/translations/es.ts +0 -43
  249. package/src/translations/fr.ts +0 -43
  250. package/src/translations/index.ts +0 -33
  251. package/src/translations/ja.ts +0 -43
  252. package/src/translations/nl.ts +0 -43
  253. package/src/translations/no.ts +0 -43
  254. package/src/translations/pt-br.ts +0 -43
  255. package/src/translations/types.ts +0 -7
  256. package/src/translations/zh.ts +0 -43
  257. package/src/types.ts +0 -46
  258. package/src/util/example.tsx +0 -129
  259. package/src/util/server.test.ts +0 -58
  260. package/src/util/server.ts +0 -47
  261. package/src/util/tryit-prefill.test.ts +0 -311
  262. package/src/util/tryit-prefill.ts +0 -160
  263. package/src/utils.ts +0 -255
@@ -1,136 +0,0 @@
1
- 'use client';
2
- import clsx from 'clsx';
3
- import type { MediaTypeRenderer } from './OpenAPICodeSample';
4
- import { OpenAPISelect, OpenAPISelectItem, useSelectState } from './OpenAPISelect';
5
- import { createStateKey } from './utils';
6
-
7
- export function OpenAPIMediaTypeExamplesSelector(props: {
8
- method: string;
9
- path: string;
10
- renderers: MediaTypeRenderer[];
11
- selectIcon?: React.ReactNode;
12
- blockKey?: string;
13
- }) {
14
- const { method, path, renderers, selectIcon, blockKey } = props;
15
- if (!renderers[0]) {
16
- throw new Error('No renderers provided');
17
- }
18
- const stateKey = createStateKey('request-body-media-type', blockKey);
19
- const state = useSelectState(stateKey, renderers[0].mediaType);
20
- const selected = renderers.find((r) => r.mediaType === state.key) || renderers[0];
21
-
22
- return (
23
- <div className="openapi-codesample-selectors">
24
- <MediaTypeSelector selectIcon={selectIcon} stateKey={stateKey} renderers={renderers} />
25
- <ExamplesSelector
26
- selectIcon={selectIcon}
27
- method={method}
28
- path={path}
29
- renderer={selected}
30
- />
31
- </div>
32
- );
33
- }
34
-
35
- function MediaTypeSelector(props: {
36
- stateKey: string;
37
- renderers: MediaTypeRenderer[];
38
- selectIcon?: React.ReactNode;
39
- }) {
40
- const { renderers, stateKey, selectIcon } = props;
41
-
42
- if (renderers.length < 2) {
43
- return null;
44
- }
45
-
46
- const items = renderers.map((renderer) => ({
47
- key: renderer.mediaType,
48
- label: renderer.mediaType,
49
- }));
50
-
51
- return (
52
- <OpenAPISelect
53
- className={clsx('openapi-select')}
54
- items={renderers.map((renderer) => ({
55
- key: renderer.mediaType,
56
- label: renderer.mediaType,
57
- }))}
58
- icon={selectIcon}
59
- stateKey={stateKey}
60
- placement="bottom start"
61
- >
62
- {items.map((item) => (
63
- <OpenAPISelectItem key={item.key} id={item.key} value={item}>
64
- {item.label}
65
- </OpenAPISelectItem>
66
- ))}
67
- </OpenAPISelect>
68
- );
69
- }
70
-
71
- function ExamplesSelector(props: {
72
- method: string;
73
- path: string;
74
- renderer: MediaTypeRenderer;
75
- selectIcon?: React.ReactNode;
76
- }) {
77
- const { method, path, renderer, selectIcon } = props;
78
- if (renderer.examples.length < 2) {
79
- return null;
80
- }
81
-
82
- const items = renderer.examples.map((example, index) => ({
83
- key: index,
84
- label: example.example.summary || `Example ${index + 1}`,
85
- }));
86
-
87
- return (
88
- <OpenAPISelect
89
- items={items}
90
- icon={selectIcon}
91
- stateKey={`media-type-sample-${renderer.mediaType}-${method}-${path}`}
92
- placement="bottom start"
93
- >
94
- {items.map((item) => (
95
- <OpenAPISelectItem key={item.key} id={item.key} value={item}>
96
- {item.label}
97
- </OpenAPISelectItem>
98
- ))}
99
- </OpenAPISelect>
100
- );
101
- }
102
-
103
- export function OpenAPIMediaTypeExamplesBody(props: {
104
- method: string;
105
- path: string;
106
- renderers: MediaTypeRenderer[];
107
- blockKey?: string;
108
- }) {
109
- const { renderers, method, path, blockKey } = props;
110
- if (!renderers[0]) {
111
- throw new Error('No renderers provided');
112
- }
113
-
114
- const mediaTypeState = useSelectState(
115
- createStateKey('request-body-media-type', blockKey),
116
- renderers[0].mediaType
117
- );
118
- const selected = renderers.find((r) => r.mediaType === mediaTypeState.key) ?? renderers[0];
119
- if (selected.examples.length === 0) {
120
- return selected.element;
121
- }
122
- return <ExamplesBody method={method} path={path} renderer={selected} />;
123
- }
124
-
125
- function ExamplesBody(props: { method: string; path: string; renderer: MediaTypeRenderer }) {
126
- const { method, path, renderer } = props;
127
- const exampleState = useSelectState(
128
- `media-type-sample-${renderer.mediaType}-${method}-${path}`,
129
- renderer.mediaType
130
- );
131
- const example = renderer.examples[Number(exampleState.key)] ?? renderer.examples[0];
132
- if (!example) {
133
- throw new Error(`No example found for key ${exampleState.key}`);
134
- }
135
- return example.element;
136
- }
@@ -1,94 +0,0 @@
1
- 'use client';
2
-
3
- import { useCallback } from 'react';
4
- import type { Key } from 'react-aria';
5
- import { useStore } from 'zustand';
6
- import { OpenAPIPath } from './OpenAPIPath';
7
- import { OpenAPISelect, OpenAPISelectItem } from './OpenAPISelect';
8
- import { StaticSection } from './StaticSection';
9
- import type { OpenAPIClientContext } from './context';
10
- import { getOrCreateStoreByKey } from './getOrCreateStoreByKey';
11
- import type { OpenAPIOperationData } from './types';
12
-
13
- function useCodeSampleState(initialKey: Key = 'default') {
14
- const store = useStore(getOrCreateStoreByKey('codesample', initialKey));
15
- return {
16
- key: store.key,
17
- setKey: useCallback((key: Key) => store.setKey(key), [store.setKey]),
18
- };
19
- }
20
-
21
- type CodeSampleItem = OpenAPISelectItem & {
22
- body: React.ReactNode;
23
- footer?: React.ReactNode;
24
- };
25
-
26
- function OpenAPICodeSampleHeader(props: {
27
- items: CodeSampleItem[];
28
- data: OpenAPIOperationData;
29
- selectIcon?: React.ReactNode;
30
- context: OpenAPIClientContext;
31
- }) {
32
- const { data, items, selectIcon, context } = props;
33
-
34
- return (
35
- <>
36
- <OpenAPIPath context={context} canCopy={false} withServer={false} data={data} />
37
- {items.length > 1 ? (
38
- <OpenAPISelect
39
- icon={selectIcon}
40
- items={items}
41
- stateKey="codesample"
42
- placement="bottom end"
43
- >
44
- {items.map((item) => (
45
- <OpenAPISelectItem key={item.key} id={item.key} value={item}>
46
- {item.label}
47
- </OpenAPISelectItem>
48
- ))}
49
- </OpenAPISelect>
50
- ) : items[0] ? (
51
- <span className="openapi-codesample-label">{items[0].label}</span>
52
- ) : null}
53
- </>
54
- );
55
- }
56
-
57
- export function OpenAPICodeSampleBody(props: {
58
- items: CodeSampleItem[];
59
- data: OpenAPIOperationData;
60
- selectIcon?: React.ReactNode;
61
- context: OpenAPIClientContext;
62
- }) {
63
- const { items, data, selectIcon, context } = props;
64
- if (!items[0]) {
65
- throw new Error('No items provided');
66
- }
67
-
68
- const state = useCodeSampleState(items[0]?.key);
69
-
70
- const selected = items.find((item) => item.key === state.key) || items[0];
71
-
72
- if (!selected) {
73
- return null;
74
- }
75
-
76
- return (
77
- <StaticSection
78
- header={
79
- <OpenAPICodeSampleHeader
80
- context={context}
81
- selectIcon={selectIcon}
82
- data={data}
83
- items={items}
84
- />
85
- }
86
- className="openapi-codesample"
87
- >
88
- <div id={selected.key as string} className="openapi-codesample-panel">
89
- {selected.body ? selected.body : null}
90
- {selected.footer ? selected.footer : null}
91
- </div>
92
- </StaticSection>
93
- );
94
- }
@@ -1,72 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { Button, type ButtonProps, Tooltip, TooltipTrigger } from 'react-aria-components';
5
- import type { OpenAPIClientContext } from './context';
6
- import { t } from './translate';
7
-
8
- export function OpenAPICopyButton(
9
- props: ButtonProps & {
10
- value: string;
11
- children: React.ReactNode;
12
- context: OpenAPIClientContext;
13
- label?: string;
14
- /**
15
- * Whether to show a tooltip.
16
- * @default true
17
- */
18
- withTooltip?: boolean;
19
- }
20
- ) {
21
- const { value, label, children, onPress, className, context, withTooltip = true } = props;
22
- const [copied, setCopied] = useState(false);
23
- const [isOpen, setIsOpen] = useState(false);
24
-
25
- const handleCopy = () => {
26
- if (!value) return;
27
- navigator.clipboard.writeText(value).then(() => {
28
- setIsOpen(true);
29
- setCopied(true);
30
-
31
- setTimeout(() => {
32
- setCopied(false);
33
- setIsOpen(false);
34
- }, 2000);
35
- });
36
- };
37
-
38
- return (
39
- <TooltipTrigger
40
- isOpen={isOpen}
41
- onOpenChange={setIsOpen}
42
- isDisabled={!withTooltip}
43
- closeDelay={200}
44
- delay={200}
45
- >
46
- <Button
47
- type="button"
48
- preventFocusOnPress
49
- onPress={(e) => {
50
- handleCopy();
51
- onPress?.(e);
52
- }}
53
- className={`openapi-copy-button ${className}`}
54
- {...props}
55
- >
56
- {children}
57
- </Button>
58
-
59
- <Tooltip
60
- isOpen={isOpen}
61
- onOpenChange={setIsOpen}
62
- placement="top"
63
- offset={4}
64
- className="openapi-tooltip"
65
- >
66
- {copied
67
- ? t(context.translation, 'copied')
68
- : label || t(context.translation, 'copy_to_clipboard')}
69
- </Tooltip>
70
- </TooltipTrigger>
71
- );
72
- }
@@ -1,46 +0,0 @@
1
- 'use client';
2
- import clsx from 'clsx';
3
- import type React from 'react';
4
- import { useState } from 'react';
5
- import { Button, Disclosure, DisclosurePanel } from 'react-aria-components';
6
-
7
- /**
8
- * Display an interactive OpenAPI disclosure.
9
- */
10
- export function OpenAPIDisclosure(props: {
11
- icon: React.ReactNode;
12
- header: React.ReactNode;
13
- children: React.ReactNode;
14
- label: string | ((isExpanded: boolean) => string);
15
- className?: string;
16
- }): React.JSX.Element {
17
- const { icon, header, label, children, className } = props;
18
- const [isExpanded, setIsExpanded] = useState(false);
19
-
20
- return (
21
- <Disclosure
22
- className={clsx('openapi-disclosure', className)}
23
- isExpanded={isExpanded}
24
- onExpandedChange={setIsExpanded}
25
- >
26
- <Button
27
- slot="trigger"
28
- className="openapi-disclosure-trigger"
29
- style={({ isFocusVisible }) => ({
30
- outline: isFocusVisible
31
- ? '2px solid rgb(var(--primary-color-500) / 0.4)'
32
- : 'none',
33
- })}
34
- >
35
- {header}
36
- <div className="openapi-disclosure-trigger-label">
37
- <span>{typeof label === 'function' ? label(isExpanded) : label}</span>
38
- {icon}
39
- </div>
40
- </Button>
41
- <DisclosurePanel className="openapi-disclosure-panel">
42
- {isExpanded ? children : null}
43
- </DisclosurePanel>
44
- </Disclosure>
45
- );
46
- }
@@ -1,158 +0,0 @@
1
- 'use client';
2
-
3
- import { createContext, useContext, useRef } from 'react';
4
- import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
5
- import {
6
- type DisclosureGroupProps,
7
- type DisclosureGroupState,
8
- useDisclosureGroupState,
9
- useDisclosureState,
10
- } from 'react-stately';
11
- import { OpenAPISelect, OpenAPISelectItem, useSelectState } from './OpenAPISelect';
12
-
13
- interface Props {
14
- groups: TDisclosureGroup[];
15
- icon?: React.ReactNode;
16
- /** State key to use with a store */
17
- selectStateKey?: string;
18
- /** Icon to display for the select */
19
- selectIcon?: React.ReactNode;
20
- }
21
-
22
- type TDisclosureGroup = {
23
- key: string;
24
- label: string | React.ReactNode;
25
- tabs?: {
26
- key: string;
27
- label: string | React.ReactNode;
28
- body?: React.ReactNode;
29
- }[];
30
- };
31
-
32
- const DisclosureGroupStateContext = createContext<DisclosureGroupState | null>(null);
33
-
34
- /**
35
- * Display an interactive OpenAPI disclosure group.
36
- */
37
- export function OpenAPIDisclosureGroup(props: DisclosureGroupProps & Props) {
38
- const { icon, groups, selectStateKey, selectIcon } = props;
39
-
40
- const state = useDisclosureGroupState(props);
41
-
42
- return (
43
- <DisclosureGroupStateContext.Provider value={state}>
44
- {groups.map((group) => (
45
- <DisclosureItem
46
- selectStateKey={selectStateKey}
47
- selectIcon={selectIcon}
48
- icon={icon}
49
- key={group.key}
50
- group={group}
51
- />
52
- ))}
53
- </DisclosureGroupStateContext.Provider>
54
- );
55
- }
56
-
57
- function DisclosureItem(props: {
58
- group: TDisclosureGroup;
59
- icon?: React.ReactNode;
60
- selectStateKey?: string;
61
- selectIcon?: React.ReactNode;
62
- }) {
63
- const { icon, group, selectStateKey, selectIcon } = props;
64
-
65
- const defaultId = useId();
66
- const id = group.key || defaultId;
67
- const groupState = useContext(DisclosureGroupStateContext);
68
- const isExpanded = groupState?.expandedKeys.has(id) || false;
69
- const state = useDisclosureState({
70
- isExpanded,
71
- onExpandedChange() {
72
- if (groupState) {
73
- groupState.toggleKey(id);
74
- }
75
- },
76
- });
77
-
78
- const panelRef = useRef<HTMLDivElement | null>(null);
79
- const triggerRef = useRef<HTMLDivElement | null>(null);
80
- const isDisabled = groupState?.isDisabled || !group.tabs?.length || false;
81
- const { buttonProps: triggerProps, panelProps } = useDisclosure(
82
- {
83
- ...props,
84
- isExpanded,
85
- isDisabled,
86
- },
87
- state,
88
- panelRef
89
- );
90
- const { buttonProps } = useButton(triggerProps, triggerRef);
91
- const { isFocusVisible, focusProps } = useFocusRing();
92
-
93
- const defaultTab = group.tabs?.[0]?.key || '';
94
- const store = useSelectState(selectStateKey, defaultTab);
95
- const selectedTab = group.tabs?.find((tab) => tab.key === store.key) || group.tabs?.[0];
96
-
97
- return (
98
- <div className="openapi-disclosure-group" aria-expanded={state.isExpanded}>
99
- <div
100
- slot="trigger"
101
- ref={triggerRef}
102
- {...mergeProps(buttonProps, focusProps)}
103
- aria-disabled={isDisabled}
104
- style={{
105
- outline: isFocusVisible
106
- ? '2px solid rgb(var(--primary-color-500)/0.4)'
107
- : 'none',
108
- }}
109
- className="openapi-disclosure-group-trigger"
110
- >
111
- <div className="openapi-disclosure-group-icon">
112
- {icon || (
113
- <svg viewBox="0 0 24 24" className="openapi-disclosure-group-icon">
114
- <path d="m8.25 4.5 7.5 7.5-7.5 7.5" />
115
- </svg>
116
- )}
117
- </div>
118
-
119
- <div className="openapi-disclosure-group-label">
120
- {group.label}
121
-
122
- {group.tabs ? (
123
- <div
124
- className="openapi-disclosure-group-mediatype"
125
- onClick={(e) => e.stopPropagation()}
126
- >
127
- {group.tabs?.length > 1 ? (
128
- <OpenAPISelect
129
- icon={selectIcon}
130
- stateKey={selectStateKey}
131
- onSelectionChange={() => {
132
- state.expand();
133
- }}
134
- items={group.tabs}
135
- placement="bottom end"
136
- >
137
- {group.tabs.map((tab) => (
138
- <OpenAPISelectItem key={tab.key} id={tab.key} value={tab}>
139
- {tab.label}
140
- </OpenAPISelectItem>
141
- ))}
142
- </OpenAPISelect>
143
- ) : group.tabs[0]?.label ? (
144
- <span>{group.tabs[0].label}</span>
145
- ) : null}
146
- </div>
147
- ) : null}
148
- </div>
149
- </div>
150
-
151
- {state.isExpanded && selectedTab && (
152
- <div className="openapi-disclosure-group-panel" ref={panelRef} {...panelProps}>
153
- {selectedTab.body}
154
- </div>
155
- )}
156
- </div>
157
- );
158
- }
@@ -1,55 +0,0 @@
1
- import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
- import type { OpenAPIContext, OpenAPIUniversalContext } from './context';
3
- import { json2xml } from './json2xml';
4
- import { stringifyOpenAPI } from './stringifyOpenAPI';
5
- import { t } from './translate';
6
-
7
- /**
8
- * Display an example.
9
- */
10
- export function OpenAPIExample(props: {
11
- example: OpenAPIV3.ExampleObject;
12
- context: OpenAPIContext;
13
- syntax: string;
14
- }) {
15
- const { example, context, syntax } = props;
16
- const code = stringifyExample({ example, xml: syntax === 'xml' });
17
-
18
- if (code === null) {
19
- return <OpenAPIEmptyExample context={context} />;
20
- }
21
-
22
- return context.renderCodeBlock({ code, syntax });
23
- }
24
-
25
- function stringifyExample(args: { example: OpenAPIV3.ExampleObject; xml: boolean }): string | null {
26
- const { example, xml } = args;
27
-
28
- if (!example.value) {
29
- return null;
30
- }
31
-
32
- if (typeof example.value === 'string') {
33
- return example.value;
34
- }
35
-
36
- if (xml) {
37
- return json2xml(example.value);
38
- }
39
-
40
- return stringifyOpenAPI(example.value, null, 2);
41
- }
42
-
43
- /**
44
- * Empty response example.
45
- */
46
- export function OpenAPIEmptyExample(props: {
47
- context: OpenAPIUniversalContext;
48
- }) {
49
- const { context } = props;
50
- return (
51
- <pre className="openapi-example-empty">
52
- <p>{t(context.translation, 'no_content')}</p>
53
- </pre>
54
- );
55
- }
@@ -1,139 +0,0 @@
1
- 'use client';
2
-
3
- import type { Key } from 'react-aria';
4
- import { OpenAPIEmptyExample } from './OpenAPIExample';
5
- import { OpenAPISelect, OpenAPISelectItem, useSelectState } from './OpenAPISelect';
6
- import { StaticSection } from './StaticSection';
7
- import type { OpenAPIClientContext } from './context';
8
-
9
- type OpenAPIMediaTypeItem = OpenAPISelectItem & {
10
- body: React.ReactNode;
11
- examples?: OpenAPIMediaTypeItem[];
12
- };
13
-
14
- /**
15
- * Get the state of the response examples select.
16
- */
17
- export function useMediaTypesState(stateKey: string | undefined, initialKey: Key = 'default') {
18
- return useSelectState(stateKey, initialKey);
19
- }
20
-
21
- function useMediaTypeExamplesState(stateKey: string | undefined, initialKey: Key = 'default') {
22
- return useSelectState(stateKey, initialKey);
23
- }
24
-
25
- export function OpenAPIMediaTypeContent(props: {
26
- items: OpenAPIMediaTypeItem[];
27
- selectIcon?: React.ReactNode;
28
- stateKey: string;
29
- context: OpenAPIClientContext;
30
- }) {
31
- const { stateKey, items, selectIcon, context } = props;
32
- const state = useMediaTypesState(stateKey, items[0]?.key);
33
-
34
- const examples = items.find((item) => item.key === state.key)?.examples ?? [];
35
-
36
- if (!items.length && !examples.length) {
37
- return null;
38
- }
39
-
40
- return (
41
- <StaticSection
42
- footer={
43
- items.length > 1 || examples.length > 1 ? (
44
- <OpenAPIMediaTypeFooter
45
- items={items}
46
- examples={examples}
47
- selectIcon={selectIcon}
48
- stateKey={stateKey}
49
- />
50
- ) : null
51
- }
52
- className="openapi-response-media-types-examples"
53
- >
54
- <OpenAPIMediaTypeBody
55
- context={context}
56
- stateKey={stateKey}
57
- items={items}
58
- examples={examples}
59
- />
60
- </StaticSection>
61
- );
62
- }
63
-
64
- function OpenAPIMediaTypeFooter(props: {
65
- items: OpenAPIMediaTypeItem[];
66
- examples?: OpenAPIMediaTypeItem[];
67
- selectIcon?: React.ReactNode;
68
- stateKey: string;
69
- }) {
70
- const { items, examples, stateKey, selectIcon } = props;
71
-
72
- return (
73
- <>
74
- {items.length > 1 && (
75
- <OpenAPISelect
76
- icon={selectIcon}
77
- items={items}
78
- stateKey={stateKey}
79
- placement="bottom start"
80
- >
81
- {items.map((item) => (
82
- <OpenAPISelectItem key={item.key} id={item.key} value={item}>
83
- <span>{item.label}</span>
84
- </OpenAPISelectItem>
85
- ))}
86
- </OpenAPISelect>
87
- )}
88
-
89
- {examples && examples.length > 1 ? (
90
- <OpenAPISelect
91
- icon={selectIcon}
92
- items={examples}
93
- stateKey={`${stateKey}-examples`}
94
- placement="bottom start"
95
- >
96
- {examples.map((example) => (
97
- <OpenAPISelectItem key={example.key} id={example.key} value={example}>
98
- <span>{example.label}</span>
99
- </OpenAPISelectItem>
100
- ))}
101
- </OpenAPISelect>
102
- ) : null}
103
- </>
104
- );
105
- }
106
-
107
- function OpenAPIMediaTypeBody(props: {
108
- items: OpenAPIMediaTypeItem[];
109
- examples?: OpenAPIMediaTypeItem[];
110
- stateKey: string;
111
- context: OpenAPIClientContext;
112
- }) {
113
- const { stateKey, items, examples, context } = props;
114
- const state = useMediaTypesState(stateKey, items[0]?.key);
115
-
116
- const selectedItem = items.find((item) => item.key === state.key) ?? items[0];
117
-
118
- const exampleState = useMediaTypeExamplesState(
119
- `${stateKey}-examples`,
120
- selectedItem?.examples?.[0]?.key
121
- );
122
-
123
- if (!selectedItem) {
124
- return null;
125
- }
126
-
127
- if (examples) {
128
- const selectedExample =
129
- examples.find((example) => example.key === exampleState.key) ?? examples[0];
130
-
131
- if (!selectedExample) {
132
- return <OpenAPIEmptyExample context={context} />;
133
- }
134
-
135
- return selectedExample.body;
136
- }
137
-
138
- return selectedItem.body;
139
- }