@stoplight/elements 9.0.11 → 9.0.12-beta-0.1
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.
- package/.storybook/main.js +6 -0
- package/.storybook/manager.js +1 -0
- package/.storybook/preview.jsx +3 -0
- package/jest.config.js +7 -0
- package/package.json +76 -16
- package/src/__fixtures__/api-descriptions/Instagram.ts +1859 -0
- package/src/__fixtures__/api-descriptions/badgesForSchema.ts +36 -0
- package/src/__fixtures__/api-descriptions/simpleApiWithInternalOperations.ts +253 -0
- package/src/__fixtures__/api-descriptions/simpleApiWithoutDescription.ts +243 -0
- package/src/__fixtures__/api-descriptions/todosApiBundled.ts +430 -0
- package/src/__fixtures__/api-descriptions/zoomApiYaml.ts +6083 -0
- package/src/components/API/APIWithResponsiveSidebarLayout.tsx +125 -0
- package/src/components/API/APIWithSidebarLayout.tsx +158 -0
- package/src/components/API/APIWithStackedLayout.tsx +286 -0
- package/src/components/API/__tests__/utils.test.ts +1323 -0
- package/src/components/API/utils.ts +206 -0
- package/src/containers/API.spec.tsx +122 -0
- package/src/containers/API.stories.tsx +117 -0
- package/src/containers/API.tsx +277 -0
- package/src/containers/story-helper.tsx +53 -0
- package/src/hooks/useExportDocumentProps.spec.tsx +68 -0
- package/src/hooks/useExportDocumentProps.tsx +48 -0
- package/src/styles.css +1 -0
- package/src/utils/oas/__tests__/oas.spec.ts +411 -0
- package/src/utils/oas/index.ts +192 -0
- package/src/utils/oas/oas2.ts +31 -0
- package/src/utils/oas/oas3.ts +54 -0
- package/src/utils/oas/types.ts +34 -0
- package/src/web-components/__stories__/Api.stories.tsx +63 -0
- package/src/web-components/components.ts +26 -0
- package/src/web-components/index.ts +3 -0
- package/tsconfig.build.json +18 -0
- package/tsconfig.json +7 -0
- package/web-components.config.js +1 -0
- package/__fixtures__/api-descriptions/Instagram.d.ts +0 -1547
- package/__fixtures__/api-descriptions/badgesForSchema.d.ts +0 -1
- package/__fixtures__/api-descriptions/simpleApiWithInternalOperations.d.ts +0 -224
- package/__fixtures__/api-descriptions/simpleApiWithoutDescription.d.ts +0 -212
- package/__fixtures__/api-descriptions/todosApiBundled.d.ts +0 -1
- package/__fixtures__/api-descriptions/zoomApiYaml.d.ts +0 -1
- package/components/API/APIWithResponsiveSidebarLayout.d.ts +0 -25
- package/components/API/APIWithSidebarLayout.d.ts +0 -32
- package/components/API/APIWithStackedLayout.d.ts +0 -29
- package/components/API/utils.d.ts +0 -20
- package/containers/API.d.ts +0 -30
- package/containers/API.spec.d.ts +0 -1
- package/containers/API.stories.d.ts +0 -58
- package/containers/story-helper.d.ts +0 -2
- package/hooks/useExportDocumentProps.d.ts +0 -11
- package/hooks/useExportDocumentProps.spec.d.ts +0 -1
- package/index.esm.js +0 -657
- package/index.js +0 -681
- package/index.mjs +0 -657
- package/styles.min.css +0 -1
- package/utils/oas/index.d.ts +0 -3
- package/utils/oas/oas2.d.ts +0 -2
- package/utils/oas/oas3.d.ts +0 -2
- package/utils/oas/types.d.ts +0 -33
- package/web-components/components.d.ts +0 -1
- package/web-components/index.d.ts +0 -1
- package/web-components.min.js +0 -2
- package/web-components.min.js.LICENSE.txt +0 -176
- /package/{index.d.ts → src/index.ts} +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isHttpOperation,
|
|
3
|
+
isHttpService,
|
|
4
|
+
isHttpWebhookOperation,
|
|
5
|
+
resolveUrl,
|
|
6
|
+
TableOfContentsGroup,
|
|
7
|
+
TableOfContentsItem,
|
|
8
|
+
} from '@stoplight/elements-core';
|
|
9
|
+
import { NodeType } from '@stoplight/types';
|
|
10
|
+
import { JSONSchema7 } from 'json-schema';
|
|
11
|
+
import { defaults } from 'lodash';
|
|
12
|
+
|
|
13
|
+
import { OperationNode, SchemaNode, ServiceChildNode, ServiceNode, WebhookNode } from '../../utils/oas/types';
|
|
14
|
+
|
|
15
|
+
type GroupableNode = OperationNode | WebhookNode | SchemaNode;
|
|
16
|
+
|
|
17
|
+
export type TagGroup<T extends GroupableNode> = { title: string; items: T[] };
|
|
18
|
+
|
|
19
|
+
export function computeTagGroups<T extends GroupableNode>(serviceNode: ServiceNode, nodeType: T['type']) {
|
|
20
|
+
const groupsByTagId: { [tagId: string]: TagGroup<T> } = {};
|
|
21
|
+
const ungrouped: T[] = [];
|
|
22
|
+
|
|
23
|
+
const lowerCaseServiceTags = serviceNode.tags.map(tn => tn.toLowerCase());
|
|
24
|
+
|
|
25
|
+
const groupableNodes = serviceNode.children.filter(n => n.type === nodeType) as T[];
|
|
26
|
+
|
|
27
|
+
for (const node of groupableNodes) {
|
|
28
|
+
for (const tagName of node.tags) {
|
|
29
|
+
const tagId = tagName.toLowerCase();
|
|
30
|
+
if (groupsByTagId[tagId]) {
|
|
31
|
+
groupsByTagId[tagId].items.push(node);
|
|
32
|
+
} else {
|
|
33
|
+
const serviceTagIndex = lowerCaseServiceTags.findIndex(tn => tn === tagId);
|
|
34
|
+
const serviceTagName = serviceNode.tags[serviceTagIndex];
|
|
35
|
+
groupsByTagId[tagId] = {
|
|
36
|
+
title: serviceTagName || tagName,
|
|
37
|
+
items: [node],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (node.tags.length === 0) {
|
|
42
|
+
ungrouped.push(node);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const orderedTagGroups = Object.entries(groupsByTagId)
|
|
47
|
+
.sort(([g1], [g2]) => {
|
|
48
|
+
const g1LC = g1.toLowerCase();
|
|
49
|
+
const g2LC = g2.toLowerCase();
|
|
50
|
+
const g1Idx = lowerCaseServiceTags.findIndex(tn => tn === g1LC);
|
|
51
|
+
const g2Idx = lowerCaseServiceTags.findIndex(tn => tn === g2LC);
|
|
52
|
+
|
|
53
|
+
// Move not-tagged groups to the bottom
|
|
54
|
+
if (g1Idx < 0 && g2Idx < 0) return 0;
|
|
55
|
+
if (g1Idx < 0) return 1;
|
|
56
|
+
if (g2Idx < 0) return -1;
|
|
57
|
+
|
|
58
|
+
// sort tagged groups according to the order found in HttpService
|
|
59
|
+
return g1Idx - g2Idx;
|
|
60
|
+
})
|
|
61
|
+
.map(([, tagGroup]) => tagGroup);
|
|
62
|
+
|
|
63
|
+
return { groups: orderedTagGroups, ungrouped };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface ComputeAPITreeConfig {
|
|
67
|
+
hideSchemas?: boolean;
|
|
68
|
+
hideInternal?: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const defaultComputerAPITreeConfig = {
|
|
72
|
+
hideSchemas: false,
|
|
73
|
+
hideInternal: false,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const computeAPITree = (serviceNode: ServiceNode, config: ComputeAPITreeConfig = {}) => {
|
|
77
|
+
const mergedConfig = defaults(config, defaultComputerAPITreeConfig);
|
|
78
|
+
const tree: TableOfContentsItem[] = [];
|
|
79
|
+
|
|
80
|
+
tree.push({
|
|
81
|
+
id: '/',
|
|
82
|
+
slug: '/',
|
|
83
|
+
title: 'Overview',
|
|
84
|
+
type: 'overview',
|
|
85
|
+
meta: '',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const hasOperationNodes = serviceNode.children.some(node => node.type === NodeType.HttpOperation);
|
|
89
|
+
if (hasOperationNodes) {
|
|
90
|
+
tree.push({
|
|
91
|
+
title: 'Endpoints',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const { groups, ungrouped } = computeTagGroups<OperationNode>(serviceNode, NodeType.HttpOperation);
|
|
95
|
+
addTagGroupsToTree(groups, ungrouped, tree, NodeType.HttpOperation, mergedConfig.hideInternal);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const hasWebhookNodes = serviceNode.children.some(node => node.type === NodeType.HttpWebhook);
|
|
99
|
+
if (hasWebhookNodes) {
|
|
100
|
+
tree.push({
|
|
101
|
+
title: 'Webhooks',
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const { groups, ungrouped } = computeTagGroups<WebhookNode>(serviceNode, NodeType.HttpWebhook);
|
|
105
|
+
addTagGroupsToTree(groups, ungrouped, tree, NodeType.HttpWebhook, mergedConfig.hideInternal);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let schemaNodes = serviceNode.children.filter(node => node.type === NodeType.Model);
|
|
109
|
+
if (mergedConfig.hideInternal) {
|
|
110
|
+
schemaNodes = schemaNodes.filter(n => !isInternal(n));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!mergedConfig.hideSchemas && schemaNodes.length) {
|
|
114
|
+
tree.push({
|
|
115
|
+
title: 'Schemas',
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const { groups, ungrouped } = computeTagGroups<SchemaNode>(serviceNode, NodeType.Model);
|
|
119
|
+
addTagGroupsToTree(groups, ungrouped, tree, NodeType.Model, mergedConfig.hideInternal);
|
|
120
|
+
}
|
|
121
|
+
return tree;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const findFirstNodeSlug = (tree: TableOfContentsItem[]): string | void => {
|
|
125
|
+
for (const item of tree) {
|
|
126
|
+
if ('slug' in item) {
|
|
127
|
+
return item.slug;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if ('items' in item) {
|
|
131
|
+
const slug = findFirstNodeSlug(item.items);
|
|
132
|
+
if (slug) {
|
|
133
|
+
return slug;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const isInternal = (node: ServiceChildNode | ServiceNode): boolean => {
|
|
142
|
+
const data = node.data;
|
|
143
|
+
|
|
144
|
+
if (isHttpOperation(data) || isHttpWebhookOperation(data)) {
|
|
145
|
+
return !!data.internal;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (isHttpService(data)) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return !!data['x-internal' as keyof JSONSchema7];
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const addTagGroupsToTree = <T extends GroupableNode>(
|
|
156
|
+
groups: TagGroup<T>[],
|
|
157
|
+
ungrouped: T[],
|
|
158
|
+
tree: TableOfContentsItem[],
|
|
159
|
+
itemsType: TableOfContentsGroup['itemsType'],
|
|
160
|
+
hideInternal: boolean,
|
|
161
|
+
) => {
|
|
162
|
+
// Show ungrouped nodes above tag groups
|
|
163
|
+
ungrouped.forEach(node => {
|
|
164
|
+
if (hideInternal && isInternal(node)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
tree.push({
|
|
168
|
+
id: node.uri,
|
|
169
|
+
slug: node.uri,
|
|
170
|
+
title: node.name,
|
|
171
|
+
type: node.type,
|
|
172
|
+
meta: isHttpOperation(node.data) || isHttpWebhookOperation(node.data) ? node.data.method : '',
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
groups.forEach(group => {
|
|
177
|
+
const items = group.items.flatMap(node => {
|
|
178
|
+
if (hideInternal && isInternal(node)) {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
id: node.uri,
|
|
183
|
+
slug: node.uri,
|
|
184
|
+
title: node.name,
|
|
185
|
+
type: node.type,
|
|
186
|
+
meta: isHttpOperation(node.data) || isHttpWebhookOperation(node.data) ? node.data.method : '',
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
if (items.length > 0) {
|
|
190
|
+
tree.push({
|
|
191
|
+
title: group.title,
|
|
192
|
+
items,
|
|
193
|
+
itemsType,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export const resolveRelativePath = (currentPath: string, basePath: string, outerRouter: boolean): string => {
|
|
200
|
+
if (!outerRouter || !basePath || basePath === '/') {
|
|
201
|
+
return currentPath;
|
|
202
|
+
}
|
|
203
|
+
const baseUrl = resolveUrl(basePath);
|
|
204
|
+
const currentUrl = resolveUrl(currentPath);
|
|
205
|
+
return baseUrl && currentUrl && baseUrl !== currentUrl ? currentUrl.replace(baseUrl, '') : '/';
|
|
206
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
|
|
3
|
+
import { act, render, screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
7
|
+
|
|
8
|
+
import { InstagramAPI } from '../__fixtures__/api-descriptions/Instagram';
|
|
9
|
+
import { simpleApiWithoutDescription } from '../__fixtures__/api-descriptions/simpleApiWithoutDescription';
|
|
10
|
+
import { API } from './API';
|
|
11
|
+
|
|
12
|
+
describe('API', () => {
|
|
13
|
+
const APIDocument = {
|
|
14
|
+
...InstagramAPI,
|
|
15
|
+
info: {
|
|
16
|
+
...InstagramAPI.info,
|
|
17
|
+
'x-logo': {
|
|
18
|
+
...InstagramAPI.info['x-logo'],
|
|
19
|
+
altText: 'instagram-logo',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// we need to add scrollTo to the Element prototype before we mount so it has the method available
|
|
25
|
+
Element.prototype.scrollTo = () => {};
|
|
26
|
+
|
|
27
|
+
it('displays logo specified in x-logo property of API document', async () => {
|
|
28
|
+
render(<API layout="sidebar" apiDescriptionDocument={InstagramAPI} />);
|
|
29
|
+
|
|
30
|
+
// checks if altText defaults to "logo" if the prop is not passed in API document
|
|
31
|
+
// checks if logo is present
|
|
32
|
+
expect(await screen.findByAltText('logo')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('uses the altText property from the API document', async () => {
|
|
36
|
+
render(<API layout="sidebar" apiDescriptionDocument={APIDocument} />);
|
|
37
|
+
|
|
38
|
+
expect(await screen.findByAltText('instagram-logo')).toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("doesn't display the logo when no properties are passed neither via API document nor as component prop", () => {
|
|
42
|
+
render(<API layout="sidebar" apiDescriptionDocument={simpleApiWithoutDescription} />);
|
|
43
|
+
|
|
44
|
+
expect(screen.queryByAltText('logo')).not.toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('overrides the logo from API document with the one passed in a prop', async () => {
|
|
48
|
+
render(<API logo="thisisarequiredprop" layout="sidebar" apiDescriptionDocument={APIDocument} />);
|
|
49
|
+
|
|
50
|
+
expect(screen.queryByAltText('instagram-logo')).not.toBeInTheDocument();
|
|
51
|
+
expect(await screen.findByAltText('logo')).toBeInTheDocument();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('displays internal operations by default', () => {
|
|
55
|
+
const { unmount } = render(
|
|
56
|
+
<MemoryRouter initialEntries={['/paths/internal-operation/get']}>
|
|
57
|
+
<API layout="sidebar" apiDescriptionDocument={APIDocument} />
|
|
58
|
+
</MemoryRouter>,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(screen.getByText('If you see this, something went wrong')).toBeInTheDocument();
|
|
62
|
+
|
|
63
|
+
unmount();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('displays internal models by default', () => {
|
|
67
|
+
render(
|
|
68
|
+
<MemoryRouter initialEntries={['/schemas/InternalObject']}>
|
|
69
|
+
<API layout="sidebar" apiDescriptionDocument={APIDocument} />
|
|
70
|
+
</MemoryRouter>,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(screen.getByText('Cool object, but internal.')).toBeInTheDocument();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('reroutes to main page on internal operation if hideInternal is on', () => {
|
|
77
|
+
render(
|
|
78
|
+
<MemoryRouter initialEntries={['/paths/internal-operation/get']}>
|
|
79
|
+
<API layout="sidebar" apiDescriptionDocument={APIDocument} hideInternal />
|
|
80
|
+
</MemoryRouter>,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
expect(screen.queryByText('If you see this, something went wrong')).not.toBeInTheDocument();
|
|
84
|
+
expect(location.pathname).toBe('/');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('reroutes to main page on internal model if hideInternal is on', () => {
|
|
88
|
+
render(
|
|
89
|
+
<MemoryRouter initialEntries={['/schemas/InternalObject']}>
|
|
90
|
+
<API layout="sidebar" apiDescriptionDocument={APIDocument} hideInternal />
|
|
91
|
+
</MemoryRouter>,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(screen.queryByText('Cool object, but internal.')).not.toBeInTheDocument();
|
|
95
|
+
expect(location.pathname).toBe('/');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('stackedLayout', () => {
|
|
99
|
+
it('shows operation path and method when collapsed', async () => {
|
|
100
|
+
render(<API logo="thisisarequiredprop" layout="stacked" apiDescriptionDocument={APIDocument} />);
|
|
101
|
+
|
|
102
|
+
const users = await screen.findByText('users');
|
|
103
|
+
act(() => userEvent.click(users));
|
|
104
|
+
|
|
105
|
+
expect(screen.queryByText('/users/{user-id}')).toBeInTheDocument();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('shows operation name when expanded', async () => {
|
|
109
|
+
render(<API logo="thisisarequiredprop" layout="stacked" apiDescriptionDocument={APIDocument} />);
|
|
110
|
+
|
|
111
|
+
const users = await screen.findByText('users');
|
|
112
|
+
act(() => userEvent.click(users));
|
|
113
|
+
|
|
114
|
+
const usersPath = await screen.findByText('/users/{user-id}');
|
|
115
|
+
act(() => userEvent.click(usersPath));
|
|
116
|
+
|
|
117
|
+
const usersSummary = await screen.findByText('Get basic information about a user.');
|
|
118
|
+
|
|
119
|
+
expect(usersSummary).toBeInTheDocument();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { parse } from '@stoplight/yaml';
|
|
2
|
+
import { Story } from '@storybook/react';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import { badgesForSchema } from '../__fixtures__/api-descriptions/badgesForSchema';
|
|
6
|
+
import { simpleApiWithInternalOperations } from '../__fixtures__/api-descriptions/simpleApiWithInternalOperations';
|
|
7
|
+
import { simpleApiWithoutDescription } from '../__fixtures__/api-descriptions/simpleApiWithoutDescription';
|
|
8
|
+
import { todosApiBundled } from '../__fixtures__/api-descriptions/todosApiBundled';
|
|
9
|
+
import { zoomApiYaml } from '../__fixtures__/api-descriptions/zoomApiYaml';
|
|
10
|
+
import { API, APIProps } from './API';
|
|
11
|
+
import { renderExtensionRenderer } from './story-helper';
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
title: 'Public/API',
|
|
15
|
+
component: API,
|
|
16
|
+
argTypes: {
|
|
17
|
+
apiDescriptionDocument: { control: 'text', type: { required: false }, table: { category: 'Input' } },
|
|
18
|
+
apiDescriptionUrl: { control: 'text', table: { category: 'Input' } },
|
|
19
|
+
layout: {
|
|
20
|
+
control: { type: 'inline-radio' },
|
|
21
|
+
table: { category: 'UI' },
|
|
22
|
+
},
|
|
23
|
+
basePath: { table: { category: 'Routing' } },
|
|
24
|
+
router: { table: { category: 'Routing' } },
|
|
25
|
+
},
|
|
26
|
+
args: {
|
|
27
|
+
router: 'memory',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const Template: Story<APIProps> = args => <API {...args} />;
|
|
32
|
+
|
|
33
|
+
export const APIWithYamlProvidedDirectly = Template.bind({});
|
|
34
|
+
APIWithYamlProvidedDirectly.args = {
|
|
35
|
+
apiDescriptionDocument: zoomApiYaml,
|
|
36
|
+
};
|
|
37
|
+
APIWithYamlProvidedDirectly.storyName = 'Direct YAML Input (Zoom)';
|
|
38
|
+
|
|
39
|
+
export const APIWithJSONProvidedDirectly = Template.bind({});
|
|
40
|
+
APIWithJSONProvidedDirectly.args = {
|
|
41
|
+
apiDescriptionDocument: JSON.stringify(parse(zoomApiYaml), null, ' '),
|
|
42
|
+
};
|
|
43
|
+
APIWithJSONProvidedDirectly.storyName = 'Direct JSON Input (Zoom)';
|
|
44
|
+
|
|
45
|
+
export const APIWithoutDescription = Template.bind({});
|
|
46
|
+
APIWithoutDescription.args = {
|
|
47
|
+
apiDescriptionDocument: JSON.stringify(simpleApiWithoutDescription, null, 2),
|
|
48
|
+
};
|
|
49
|
+
APIWithoutDescription.storyName = 'API Without Description';
|
|
50
|
+
|
|
51
|
+
export const APIWithInternalOperations = Template.bind({});
|
|
52
|
+
APIWithInternalOperations.args = {
|
|
53
|
+
apiDescriptionDocument: JSON.stringify(simpleApiWithInternalOperations, null, 2),
|
|
54
|
+
};
|
|
55
|
+
APIWithInternalOperations.storyName = 'API With Internal Operations';
|
|
56
|
+
|
|
57
|
+
export const OpenApi3Schema = Template.bind({});
|
|
58
|
+
OpenApi3Schema.args = {
|
|
59
|
+
apiDescriptionDocument: todosApiBundled,
|
|
60
|
+
};
|
|
61
|
+
OpenApi3Schema.storyName = 'Open Api 3.0 Schema';
|
|
62
|
+
|
|
63
|
+
export const BadgesForSchema = Template.bind({});
|
|
64
|
+
BadgesForSchema.args = {
|
|
65
|
+
apiDescriptionDocument: badgesForSchema,
|
|
66
|
+
};
|
|
67
|
+
BadgesForSchema.storyName = 'Badges For Schema';
|
|
68
|
+
|
|
69
|
+
export const StackedLayout = Template.bind({});
|
|
70
|
+
StackedLayout.args = {
|
|
71
|
+
apiDescriptionDocument: JSON.stringify(parse(zoomApiYaml), null, ' '),
|
|
72
|
+
layout: 'stacked',
|
|
73
|
+
};
|
|
74
|
+
StackedLayout.storyName = 'Stacked Layout (Zoom)';
|
|
75
|
+
|
|
76
|
+
export const ResponsiveLayout = Template.bind({});
|
|
77
|
+
ResponsiveLayout.args = {
|
|
78
|
+
apiDescriptionDocument: JSON.stringify(parse(zoomApiYaml), null, ' '),
|
|
79
|
+
layout: 'responsive',
|
|
80
|
+
};
|
|
81
|
+
ResponsiveLayout.storyName = 'Responsive Layout (Zoom)';
|
|
82
|
+
ResponsiveLayout.parameters = {
|
|
83
|
+
layout: 'fullscreen',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const Box = Template.bind({});
|
|
87
|
+
Box.args = {
|
|
88
|
+
apiDescriptionUrl: 'https://raw.githubusercontent.com/box/box-openapi/main/content/openapi.yml',
|
|
89
|
+
};
|
|
90
|
+
Box.storyName = 'Box';
|
|
91
|
+
|
|
92
|
+
export const DigitalOcean = Template.bind({});
|
|
93
|
+
DigitalOcean.args = {
|
|
94
|
+
apiDescriptionUrl:
|
|
95
|
+
'https://raw.githubusercontent.com/digitalocean/openapi/main/specification/DigitalOcean-public.v2.yaml',
|
|
96
|
+
};
|
|
97
|
+
DigitalOcean.storyName = 'DigitalOcean';
|
|
98
|
+
|
|
99
|
+
export const Github = Template.bind({});
|
|
100
|
+
Github.args = {
|
|
101
|
+
apiDescriptionUrl:
|
|
102
|
+
'https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/ghes-3.0/ghes-3.0.json',
|
|
103
|
+
};
|
|
104
|
+
Github.storyName = 'GitHub';
|
|
105
|
+
|
|
106
|
+
export const Instagram = Template.bind({});
|
|
107
|
+
Instagram.args = {
|
|
108
|
+
apiDescriptionUrl: 'https://api.apis.guru/v2/specs/instagram.com/1.0.0/swagger.yaml',
|
|
109
|
+
};
|
|
110
|
+
Instagram.storyName = 'Instagram';
|
|
111
|
+
|
|
112
|
+
export const WithExtensionRenderer = Template.bind({});
|
|
113
|
+
WithExtensionRenderer.args = {
|
|
114
|
+
renderExtensionAddon: renderExtensionRenderer,
|
|
115
|
+
apiDescriptionDocument: zoomApiYaml,
|
|
116
|
+
};
|
|
117
|
+
WithExtensionRenderer.storyName = 'With Extension Renderer';
|