@stoplight/elements-core 7.5.7 → 7.5.11
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/components/Docs/Article/index.d.ts +2 -2
- package/components/Docs/Docs.d.ts +2 -0
- package/components/MarkdownViewer/CustomComponents/ReactRouterLink.d.ts +3 -2
- package/components/MarkdownViewer/CustomComponents/ResolvedImage.d.ts +1 -1
- package/index.esm.js +23 -116
- package/index.js +15 -109
- package/index.mjs +23 -116
- package/package.json +2 -4
- package/types.d.ts +2 -14
- package/utils/guards.d.ts +2 -2
- package/components/Docs/Article/Headings.d.ts +0 -5
- package/hooks/useComponentSize.d.ts +0 -4
- package/hooks/useComputeMarkdownHeadings.d.ts +0 -4
- package/hooks/useLocationHash.d.ts +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { DocsComponentProps } from '..';
|
|
3
|
-
declare type ArticleProps = DocsComponentProps<
|
|
3
|
+
declare type ArticleProps = DocsComponentProps<IMarkdownViewerProps['markdown']>;
|
|
4
4
|
export declare const Article: import("react").FunctionComponent<ArticleProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
|
|
5
5
|
export {};
|
|
@@ -2,6 +2,7 @@ import { NodeType } from '@stoplight/types';
|
|
|
2
2
|
import { Location } from 'history';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ParsedNode } from '../../types';
|
|
5
|
+
import { ReferenceResolver } from '../../utils/ref-resolving/ReferenceResolver';
|
|
5
6
|
import { ExportButtonProps } from './HttpService/ExportButton';
|
|
6
7
|
interface BaseDocsProps {
|
|
7
8
|
className?: string;
|
|
@@ -27,6 +28,7 @@ export interface DocsProps extends BaseDocsProps {
|
|
|
27
28
|
nodeType: NodeType;
|
|
28
29
|
nodeData: unknown;
|
|
29
30
|
useNodeForRefResolving?: boolean;
|
|
31
|
+
refResolver?: ReferenceResolver;
|
|
30
32
|
}
|
|
31
33
|
export interface DocsComponentProps<T = unknown> extends BaseDocsProps {
|
|
32
34
|
data: T;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare const ReactRouterMarkdownLink: ({ title, to, href: _href, children, }: import("react").ClassAttributes<HTMLAnchorElement> & import("react").AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
2
|
+
to?: string | undefined;
|
|
3
|
+
}) => JSX.Element;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BundledBranchNode } from '../../../types';
|
|
3
|
-
export declare const createResolvedImageComponent: (branchNode: BundledBranchNode) => React.NamedExoticComponent<import("react").ImgHTMLAttributes<
|
|
3
|
+
export declare const createResolvedImageComponent: (branchNode: BundledBranchNode) => React.NamedExoticComponent<import("react").ImgHTMLAttributes<HTMLImageElement> & import("@stoplight/markdown/ast-types/hast").ImageProperties>;
|
package/index.esm.js
CHANGED
|
@@ -5,18 +5,15 @@ import { resolveInlineRef, isPlainObject as isPlainObject$1, safeParse, safeStri
|
|
|
5
5
|
import isArray from 'lodash/isArray.js';
|
|
6
6
|
import isObject from 'lodash/isObject.js';
|
|
7
7
|
import isPlainObject from 'lodash/isPlainObject.js';
|
|
8
|
-
import { parse } from '@stoplight/markdown';
|
|
9
8
|
import { NodeType, HttpParamStyles } from '@stoplight/types';
|
|
10
|
-
import { parse
|
|
11
|
-
import { isArray as isArray$1, Box,
|
|
9
|
+
import { parse } from '@stoplight/yaml';
|
|
10
|
+
import { isArray as isArray$1, Box, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
12
11
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
12
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
14
13
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
15
|
-
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
16
|
-
import throttle from 'lodash/throttle.js';
|
|
17
|
-
import { selectAll } from 'unist-util-select';
|
|
18
14
|
import cn from 'classnames';
|
|
19
15
|
import { atomWithStorage, useAtomValue } from 'jotai/utils';
|
|
16
|
+
import { faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
20
17
|
import { atom, useAtom, Provider } from 'jotai';
|
|
21
18
|
import URI from 'urijs';
|
|
22
19
|
import { CodeViewer } from '@stoplight/mosaic-code-viewer';
|
|
@@ -164,13 +161,7 @@ const parserMap = {
|
|
|
164
161
|
[NodeType.Unknown]: parseUnknown,
|
|
165
162
|
};
|
|
166
163
|
function parseArticleData(rawData) {
|
|
167
|
-
if (typeof rawData === 'string') {
|
|
168
|
-
return {
|
|
169
|
-
type: NodeType.Article,
|
|
170
|
-
data: parse(rawData),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (isSMDASTRoot(rawData)) {
|
|
164
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
174
165
|
return {
|
|
175
166
|
type: NodeType.Article,
|
|
176
167
|
data: rawData,
|
|
@@ -213,7 +204,7 @@ function tryParseYamlOrObject(yamlOrObject) {
|
|
|
213
204
|
return yamlOrObject;
|
|
214
205
|
if (typeof yamlOrObject === 'string') {
|
|
215
206
|
try {
|
|
216
|
-
return parse
|
|
207
|
+
return parse(yamlOrObject);
|
|
217
208
|
}
|
|
218
209
|
catch (e) { }
|
|
219
210
|
}
|
|
@@ -228,94 +219,9 @@ const MarkdownViewer = (props) => {
|
|
|
228
219
|
};
|
|
229
220
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
230
221
|
|
|
231
|
-
function useComponentSize(container) {
|
|
232
|
-
const [componentSize, setComponentSize] = React.useState({ width: 0, height: 0 });
|
|
233
|
-
React.useEffect(() => {
|
|
234
|
-
if (!container) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const updateComponentSize = throttle(() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
238
|
-
trailing: true,
|
|
239
|
-
});
|
|
240
|
-
updateComponentSize();
|
|
241
|
-
window.addEventListener('resize', updateComponentSize);
|
|
242
|
-
return () => {
|
|
243
|
-
updateComponentSize.cancel();
|
|
244
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
245
|
-
};
|
|
246
|
-
}, [container]);
|
|
247
|
-
return componentSize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function useComputeMarkdownHeadings(tree) {
|
|
251
|
-
return React.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
252
|
-
}
|
|
253
|
-
function computeMarkdownHeadings(tree) {
|
|
254
|
-
return selectAll(':root > [type=heading]', tree)
|
|
255
|
-
.map((heading) => {
|
|
256
|
-
var _a;
|
|
257
|
-
return ({
|
|
258
|
-
title: findTitle(heading),
|
|
259
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
260
|
-
depth: heading.depth - 1,
|
|
261
|
-
});
|
|
262
|
-
})
|
|
263
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
264
|
-
}
|
|
265
|
-
const findTitle = (parent) => {
|
|
266
|
-
return selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
function useLocationHash() {
|
|
270
|
-
const isBrowser = typeof window !== 'undefined';
|
|
271
|
-
const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
|
|
272
|
-
React.useEffect(() => {
|
|
273
|
-
if (!isBrowser)
|
|
274
|
-
return;
|
|
275
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
276
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
277
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
278
|
-
}, [isBrowser]);
|
|
279
|
-
return locationHash;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
283
|
-
const { width } = useComponentSize(container);
|
|
284
|
-
const showHeadings = width >= 768;
|
|
285
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
286
|
-
return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
287
|
-
};
|
|
288
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
289
|
-
const locationHash = useLocationHash();
|
|
290
|
-
if (!headings || !headings.length)
|
|
291
|
-
return null;
|
|
292
|
-
const component = (React.createElement(Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
293
|
-
title && (React.createElement(Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
294
|
-
React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
|
|
295
|
-
title)),
|
|
296
|
-
headings.map((heading, i) => (React.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
297
|
-
const button = React.createElement(Button, { pos: "sticky", size: "sm", borderColor: "light", icon: faStream, style: { top: 10 } });
|
|
298
|
-
if (minimal) {
|
|
299
|
-
return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
300
|
-
React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
|
|
301
|
-
React.createElement(Box, { className: className }, component))));
|
|
302
|
-
}
|
|
303
|
-
return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
304
|
-
React.createElement(Box, { borderL: true, borderColor: "light" }, component)));
|
|
305
|
-
};
|
|
306
|
-
const Heading = ({ item, isSelected }) => {
|
|
307
|
-
return (React.createElement(Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
308
|
-
};
|
|
309
|
-
|
|
310
222
|
const ArticleComponent = React.memo(({ data }) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (tree === null)
|
|
314
|
-
return null;
|
|
315
|
-
return (React.createElement(Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
316
|
-
React.createElement(Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
317
|
-
React.createElement(MarkdownViewer, { markdown: tree })),
|
|
318
|
-
React.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
223
|
+
return (React.createElement(Box, { className: "sl-elements-article" },
|
|
224
|
+
React.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
319
225
|
});
|
|
320
226
|
const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
321
227
|
|
|
@@ -1610,9 +1516,9 @@ const bodyFormatMap = {
|
|
|
1610
1516
|
text: ['raw'],
|
|
1611
1517
|
};
|
|
1612
1518
|
const regex = {
|
|
1613
|
-
image: /image\/(
|
|
1614
|
-
json: /application\/(
|
|
1615
|
-
xml: /(text|application)\/(
|
|
1519
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1520
|
+
json: /application\/(.?)*json/,
|
|
1521
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1616
1522
|
text: /text\/.*/,
|
|
1617
1523
|
};
|
|
1618
1524
|
function getResponseType(contentType) {
|
|
@@ -2177,7 +2083,7 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2177
2083
|
const hasBadges = isDeprecated || isInternal;
|
|
2178
2084
|
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
|
|
2179
2085
|
React.createElement(HStack, { spacing: 5 },
|
|
2180
|
-
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading
|
|
2086
|
+
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
|
|
2181
2087
|
React.createElement(HStack, { spacing: 2 },
|
|
2182
2088
|
isDeprecated && React.createElement(DeprecatedBadge, null),
|
|
2183
2089
|
isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
|
|
@@ -2301,7 +2207,7 @@ const HttpServiceComponent = React.memo(({ data, location = {}, layoutOptions, e
|
|
|
2301
2207
|
const query = new URLSearchParams(search);
|
|
2302
2208
|
return (React.createElement(Box, { mb: 10 },
|
|
2303
2209
|
data.name && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2304
|
-
React.createElement(Heading
|
|
2210
|
+
React.createElement(Heading, { size: 1, mb: 4, fontWeight: "semibold" }, data.name),
|
|
2305
2211
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps)))),
|
|
2306
2212
|
data.version && (React.createElement(Box, { mb: 5 },
|
|
2307
2213
|
React.createElement(VersionBadge, { value: data.version }))),
|
|
@@ -2332,7 +2238,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2332
2238
|
const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
|
|
2333
2239
|
const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2334
2240
|
React.createElement(HStack, { spacing: 5 },
|
|
2335
|
-
title && (React.createElement(Heading
|
|
2241
|
+
title && (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, title)),
|
|
2336
2242
|
React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
|
|
2337
2243
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
|
|
2338
2244
|
const description = (React.createElement(VStack, { spacing: 10 },
|
|
@@ -2347,14 +2253,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2347
2253
|
const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2348
2254
|
|
|
2349
2255
|
const Docs = React.memo((_a) => {
|
|
2350
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2256
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2351
2257
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2352
2258
|
if (!parsedNode) {
|
|
2353
2259
|
return null;
|
|
2354
2260
|
}
|
|
2355
2261
|
const parsedDocs = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2356
2262
|
if (useNodeForRefResolving) {
|
|
2357
|
-
return React.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2263
|
+
return (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2358
2264
|
}
|
|
2359
2265
|
return parsedDocs;
|
|
2360
2266
|
});
|
|
@@ -2389,7 +2295,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
|
|
|
2389
2295
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2390
2296
|
minWidth: `${sidebarWidth}px`,
|
|
2391
2297
|
} }, sidebar),
|
|
2392
|
-
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2298
|
+
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full", overflowY: "auto" },
|
|
2393
2299
|
React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2394
2300
|
});
|
|
2395
2301
|
|
|
@@ -2418,7 +2324,7 @@ function useParsedValue(value) {
|
|
|
2418
2324
|
let parsedValue = value;
|
|
2419
2325
|
if (typeof value === 'string') {
|
|
2420
2326
|
try {
|
|
2421
|
-
parsedValue = parse
|
|
2327
|
+
parsedValue = parse(value);
|
|
2422
2328
|
}
|
|
2423
2329
|
catch (error) {
|
|
2424
2330
|
}
|
|
@@ -2444,8 +2350,8 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
|
|
|
2444
2350
|
React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
|
|
2445
2351
|
};
|
|
2446
2352
|
const CodeComponent = props => {
|
|
2447
|
-
const { title, jsonSchema, http, children } = props;
|
|
2448
|
-
const value = String(Array.isArray(children) ? children[0] : children);
|
|
2353
|
+
const { title, jsonSchema, http, resolved, children } = props;
|
|
2354
|
+
const value = resolved || String(Array.isArray(children) ? children[0] : children);
|
|
2449
2355
|
const parsedValue = useParsedValue(value);
|
|
2450
2356
|
if (jsonSchema) {
|
|
2451
2357
|
if (!isJSONSchema(parsedValue)) {
|
|
@@ -2512,7 +2418,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2512
2418
|
};
|
|
2513
2419
|
|
|
2514
2420
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2515
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2421
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2422
|
+
const href = to || _href;
|
|
2516
2423
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2517
2424
|
if (isExternal) {
|
|
2518
2425
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2691,7 +2598,7 @@ const Version = ({ value }) => {
|
|
|
2691
2598
|
const NonIdealState = ({ description, icon, title }) => {
|
|
2692
2599
|
return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
|
|
2693
2600
|
React.createElement(Box, { as: Icon, icon: icon || faExclamationTriangle, color: "light", fontSize: "6xl", mb: 4 }),
|
|
2694
|
-
React.createElement(Heading
|
|
2601
|
+
React.createElement(Heading, { size: 4, mb: 4 }, title),
|
|
2695
2602
|
React.createElement(Text, null, description)));
|
|
2696
2603
|
};
|
|
2697
2604
|
|
|
@@ -2758,7 +2665,7 @@ function withRouter(WrappedComponent) {
|
|
|
2758
2665
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2759
2666
|
return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2760
2667
|
React.createElement(Route, { path: "/" },
|
|
2761
|
-
React.createElement(MarkdownComponentsProvider, { value: {
|
|
2668
|
+
React.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2762
2669
|
React.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2763
2670
|
};
|
|
2764
2671
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/index.js
CHANGED
|
@@ -8,17 +8,14 @@ var json = require('@stoplight/json');
|
|
|
8
8
|
var isArray = require('lodash/isArray.js');
|
|
9
9
|
var isObject = require('lodash/isObject.js');
|
|
10
10
|
var isPlainObject = require('lodash/isPlainObject.js');
|
|
11
|
-
var markdown = require('@stoplight/markdown');
|
|
12
11
|
var types = require('@stoplight/types');
|
|
13
12
|
var yaml = require('@stoplight/yaml');
|
|
14
13
|
var mosaic = require('@stoplight/mosaic');
|
|
15
14
|
var reactErrorBoundary = require('@stoplight/react-error-boundary');
|
|
16
15
|
var markdownViewer = require('@stoplight/markdown-viewer');
|
|
17
|
-
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
18
|
-
var throttle = require('lodash/throttle.js');
|
|
19
|
-
var unistUtilSelect = require('unist-util-select');
|
|
20
16
|
var cn = require('classnames');
|
|
21
17
|
var utils = require('jotai/utils');
|
|
18
|
+
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
22
19
|
var jotai = require('jotai');
|
|
23
20
|
var URI = require('urijs');
|
|
24
21
|
var mosaicCodeViewer = require('@stoplight/mosaic-code-viewer');
|
|
@@ -78,7 +75,6 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
|
78
75
|
var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
|
|
79
76
|
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
|
|
80
77
|
var isPlainObject__default = /*#__PURE__*/_interopDefaultLegacy(isPlainObject);
|
|
81
|
-
var throttle__default = /*#__PURE__*/_interopDefaultLegacy(throttle);
|
|
82
78
|
var cn__default = /*#__PURE__*/_interopDefaultLegacy(cn);
|
|
83
79
|
var URI__default = /*#__PURE__*/_interopDefaultLegacy(URI);
|
|
84
80
|
var HTTPSnippet__default = /*#__PURE__*/_interopDefaultLegacy(HTTPSnippet);
|
|
@@ -219,13 +215,7 @@ const parserMap = {
|
|
|
219
215
|
[types.NodeType.Unknown]: parseUnknown,
|
|
220
216
|
};
|
|
221
217
|
function parseArticleData(rawData) {
|
|
222
|
-
if (typeof rawData === 'string') {
|
|
223
|
-
return {
|
|
224
|
-
type: types.NodeType.Article,
|
|
225
|
-
data: markdown.parse(rawData),
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
if (isSMDASTRoot(rawData)) {
|
|
218
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
229
219
|
return {
|
|
230
220
|
type: types.NodeType.Article,
|
|
231
221
|
data: rawData,
|
|
@@ -283,94 +273,9 @@ const MarkdownViewer = (props) => {
|
|
|
283
273
|
};
|
|
284
274
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
285
275
|
|
|
286
|
-
function useComponentSize(container) {
|
|
287
|
-
const [componentSize, setComponentSize] = React__namespace.useState({ width: 0, height: 0 });
|
|
288
|
-
React__namespace.useEffect(() => {
|
|
289
|
-
if (!container) {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
const updateComponentSize = throttle__default["default"](() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
293
|
-
trailing: true,
|
|
294
|
-
});
|
|
295
|
-
updateComponentSize();
|
|
296
|
-
window.addEventListener('resize', updateComponentSize);
|
|
297
|
-
return () => {
|
|
298
|
-
updateComponentSize.cancel();
|
|
299
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
300
|
-
};
|
|
301
|
-
}, [container]);
|
|
302
|
-
return componentSize;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function useComputeMarkdownHeadings(tree) {
|
|
306
|
-
return React__namespace.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
307
|
-
}
|
|
308
|
-
function computeMarkdownHeadings(tree) {
|
|
309
|
-
return unistUtilSelect.selectAll(':root > [type=heading]', tree)
|
|
310
|
-
.map((heading) => {
|
|
311
|
-
var _a;
|
|
312
|
-
return ({
|
|
313
|
-
title: findTitle(heading),
|
|
314
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
315
|
-
depth: heading.depth - 1,
|
|
316
|
-
});
|
|
317
|
-
})
|
|
318
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
319
|
-
}
|
|
320
|
-
const findTitle = (parent) => {
|
|
321
|
-
return unistUtilSelect.selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
function useLocationHash() {
|
|
325
|
-
const isBrowser = typeof window !== 'undefined';
|
|
326
|
-
const [locationHash, setLocationHash] = React__namespace.useState(isBrowser && window.location.hash);
|
|
327
|
-
React__namespace.useEffect(() => {
|
|
328
|
-
if (!isBrowser)
|
|
329
|
-
return;
|
|
330
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
331
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
332
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
333
|
-
}, [isBrowser]);
|
|
334
|
-
return locationHash;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
338
|
-
const { width } = useComponentSize(container);
|
|
339
|
-
const showHeadings = width >= 768;
|
|
340
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
341
|
-
return React__namespace.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
342
|
-
};
|
|
343
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
344
|
-
const locationHash = useLocationHash();
|
|
345
|
-
if (!headings || !headings.length)
|
|
346
|
-
return null;
|
|
347
|
-
const component = (React__namespace.createElement(mosaic.Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
348
|
-
title && (React__namespace.createElement(mosaic.Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
349
|
-
React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: freeSolidSvgIcons.faStream, mr: 2 }),
|
|
350
|
-
title)),
|
|
351
|
-
headings.map((heading, i) => (React__namespace.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
352
|
-
const button = React__namespace.createElement(mosaic.Button, { pos: "sticky", size: "sm", borderColor: "light", icon: freeSolidSvgIcons.faStream, style: { top: 10 } });
|
|
353
|
-
if (minimal) {
|
|
354
|
-
return (React__namespace.createElement(mosaic.Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
355
|
-
React__namespace.createElement(mosaic.Popover, { renderTrigger: button, placement: "bottom" },
|
|
356
|
-
React__namespace.createElement(mosaic.Box, { className: className }, component))));
|
|
357
|
-
}
|
|
358
|
-
return (React__namespace.createElement(mosaic.Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
359
|
-
React__namespace.createElement(mosaic.Box, { borderL: true, borderColor: "light" }, component)));
|
|
360
|
-
};
|
|
361
|
-
const Heading = ({ item, isSelected }) => {
|
|
362
|
-
return (React__namespace.createElement(mosaic.Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
363
|
-
};
|
|
364
|
-
|
|
365
276
|
const ArticleComponent = React__namespace.memo(({ data }) => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (tree === null)
|
|
369
|
-
return null;
|
|
370
|
-
return (React__namespace.createElement(mosaic.Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
371
|
-
React__namespace.createElement(mosaic.Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
372
|
-
React__namespace.createElement(MarkdownViewer, { markdown: tree })),
|
|
373
|
-
React__namespace.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
277
|
+
return (React__namespace.createElement(mosaic.Box, { className: "sl-elements-article" },
|
|
278
|
+
React__namespace.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
374
279
|
});
|
|
375
280
|
const Article = reactErrorBoundary.withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
376
281
|
|
|
@@ -1665,9 +1570,9 @@ const bodyFormatMap = {
|
|
|
1665
1570
|
text: ['raw'],
|
|
1666
1571
|
};
|
|
1667
1572
|
const regex = {
|
|
1668
|
-
image: /image\/(
|
|
1669
|
-
json: /application\/(
|
|
1670
|
-
xml: /(text|application)\/(
|
|
1573
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1574
|
+
json: /application\/(.?)*json/,
|
|
1575
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1671
1576
|
text: /text\/.*/,
|
|
1672
1577
|
};
|
|
1673
1578
|
function getResponseType(contentType) {
|
|
@@ -2402,14 +2307,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2402
2307
|
const Model = reactErrorBoundary.withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2403
2308
|
|
|
2404
2309
|
const Docs = React__namespace.memo((_a) => {
|
|
2405
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2310
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2406
2311
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2407
2312
|
if (!parsedNode) {
|
|
2408
2313
|
return null;
|
|
2409
2314
|
}
|
|
2410
2315
|
const parsedDocs = React__namespace.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2411
2316
|
if (useNodeForRefResolving) {
|
|
2412
|
-
return React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2317
|
+
return (React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2413
2318
|
}
|
|
2414
2319
|
return parsedDocs;
|
|
2415
2320
|
});
|
|
@@ -2444,7 +2349,7 @@ const SidebarLayout = React__namespace.forwardRef(({ sidebar, children, maxConte
|
|
|
2444
2349
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2445
2350
|
minWidth: `${sidebarWidth}px`,
|
|
2446
2351
|
} }, sidebar),
|
|
2447
|
-
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2352
|
+
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full", overflowY: "auto" },
|
|
2448
2353
|
React__namespace.createElement(mosaic.Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2449
2354
|
});
|
|
2450
2355
|
|
|
@@ -2499,8 +2404,8 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
|
|
|
2499
2404
|
React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
|
|
2500
2405
|
};
|
|
2501
2406
|
const CodeComponent = props => {
|
|
2502
|
-
const { title, jsonSchema, http, children } = props;
|
|
2503
|
-
const value = String(Array.isArray(children) ? children[0] : children);
|
|
2407
|
+
const { title, jsonSchema, http, resolved, children } = props;
|
|
2408
|
+
const value = resolved || String(Array.isArray(children) ? children[0] : children);
|
|
2504
2409
|
const parsedValue = useParsedValue(value);
|
|
2505
2410
|
if (jsonSchema) {
|
|
2506
2411
|
if (!isJSONSchema(parsedValue)) {
|
|
@@ -2567,7 +2472,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2567
2472
|
};
|
|
2568
2473
|
|
|
2569
2474
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2570
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2475
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2476
|
+
const href = to || _href;
|
|
2571
2477
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2572
2478
|
if (isExternal) {
|
|
2573
2479
|
return (React__default["default"].createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2813,7 +2719,7 @@ function withRouter(WrappedComponent) {
|
|
|
2813
2719
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2814
2720
|
return (React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2815
2721
|
React__namespace.createElement(reactRouterDom.Route, { path: "/" },
|
|
2816
|
-
React__namespace.createElement(MarkdownComponentsProvider, { value: {
|
|
2722
|
+
React__namespace.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2817
2723
|
React__namespace.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2818
2724
|
};
|
|
2819
2725
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/index.mjs
CHANGED
|
@@ -5,18 +5,15 @@ import { resolveInlineRef, isPlainObject as isPlainObject$1, safeParse, safeStri
|
|
|
5
5
|
import isArray from 'lodash/isArray.js';
|
|
6
6
|
import isObject from 'lodash/isObject.js';
|
|
7
7
|
import isPlainObject from 'lodash/isPlainObject.js';
|
|
8
|
-
import { parse } from '@stoplight/markdown';
|
|
9
8
|
import { NodeType, HttpParamStyles } from '@stoplight/types';
|
|
10
|
-
import { parse
|
|
11
|
-
import { isArray as isArray$1, Box,
|
|
9
|
+
import { parse } from '@stoplight/yaml';
|
|
10
|
+
import { isArray as isArray$1, Box, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
12
11
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
12
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
14
13
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
15
|
-
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
16
|
-
import throttle from 'lodash/throttle.js';
|
|
17
|
-
import { selectAll } from 'unist-util-select';
|
|
18
14
|
import cn from 'classnames';
|
|
19
15
|
import { atomWithStorage, useAtomValue } from 'jotai/utils';
|
|
16
|
+
import { faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
20
17
|
import { atom, useAtom, Provider } from 'jotai';
|
|
21
18
|
import URI from 'urijs';
|
|
22
19
|
import { CodeViewer } from '@stoplight/mosaic-code-viewer';
|
|
@@ -164,13 +161,7 @@ const parserMap = {
|
|
|
164
161
|
[NodeType.Unknown]: parseUnknown,
|
|
165
162
|
};
|
|
166
163
|
function parseArticleData(rawData) {
|
|
167
|
-
if (typeof rawData === 'string') {
|
|
168
|
-
return {
|
|
169
|
-
type: NodeType.Article,
|
|
170
|
-
data: parse(rawData),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (isSMDASTRoot(rawData)) {
|
|
164
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
174
165
|
return {
|
|
175
166
|
type: NodeType.Article,
|
|
176
167
|
data: rawData,
|
|
@@ -213,7 +204,7 @@ function tryParseYamlOrObject(yamlOrObject) {
|
|
|
213
204
|
return yamlOrObject;
|
|
214
205
|
if (typeof yamlOrObject === 'string') {
|
|
215
206
|
try {
|
|
216
|
-
return parse
|
|
207
|
+
return parse(yamlOrObject);
|
|
217
208
|
}
|
|
218
209
|
catch (e) { }
|
|
219
210
|
}
|
|
@@ -228,94 +219,9 @@ const MarkdownViewer = (props) => {
|
|
|
228
219
|
};
|
|
229
220
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
230
221
|
|
|
231
|
-
function useComponentSize(container) {
|
|
232
|
-
const [componentSize, setComponentSize] = React.useState({ width: 0, height: 0 });
|
|
233
|
-
React.useEffect(() => {
|
|
234
|
-
if (!container) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const updateComponentSize = throttle(() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
238
|
-
trailing: true,
|
|
239
|
-
});
|
|
240
|
-
updateComponentSize();
|
|
241
|
-
window.addEventListener('resize', updateComponentSize);
|
|
242
|
-
return () => {
|
|
243
|
-
updateComponentSize.cancel();
|
|
244
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
245
|
-
};
|
|
246
|
-
}, [container]);
|
|
247
|
-
return componentSize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function useComputeMarkdownHeadings(tree) {
|
|
251
|
-
return React.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
252
|
-
}
|
|
253
|
-
function computeMarkdownHeadings(tree) {
|
|
254
|
-
return selectAll(':root > [type=heading]', tree)
|
|
255
|
-
.map((heading) => {
|
|
256
|
-
var _a;
|
|
257
|
-
return ({
|
|
258
|
-
title: findTitle(heading),
|
|
259
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
260
|
-
depth: heading.depth - 1,
|
|
261
|
-
});
|
|
262
|
-
})
|
|
263
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
264
|
-
}
|
|
265
|
-
const findTitle = (parent) => {
|
|
266
|
-
return selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
function useLocationHash() {
|
|
270
|
-
const isBrowser = typeof window !== 'undefined';
|
|
271
|
-
const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
|
|
272
|
-
React.useEffect(() => {
|
|
273
|
-
if (!isBrowser)
|
|
274
|
-
return;
|
|
275
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
276
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
277
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
278
|
-
}, [isBrowser]);
|
|
279
|
-
return locationHash;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
283
|
-
const { width } = useComponentSize(container);
|
|
284
|
-
const showHeadings = width >= 768;
|
|
285
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
286
|
-
return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
287
|
-
};
|
|
288
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
289
|
-
const locationHash = useLocationHash();
|
|
290
|
-
if (!headings || !headings.length)
|
|
291
|
-
return null;
|
|
292
|
-
const component = (React.createElement(Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
293
|
-
title && (React.createElement(Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
294
|
-
React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
|
|
295
|
-
title)),
|
|
296
|
-
headings.map((heading, i) => (React.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
297
|
-
const button = React.createElement(Button, { pos: "sticky", size: "sm", borderColor: "light", icon: faStream, style: { top: 10 } });
|
|
298
|
-
if (minimal) {
|
|
299
|
-
return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
300
|
-
React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
|
|
301
|
-
React.createElement(Box, { className: className }, component))));
|
|
302
|
-
}
|
|
303
|
-
return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
304
|
-
React.createElement(Box, { borderL: true, borderColor: "light" }, component)));
|
|
305
|
-
};
|
|
306
|
-
const Heading = ({ item, isSelected }) => {
|
|
307
|
-
return (React.createElement(Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
308
|
-
};
|
|
309
|
-
|
|
310
222
|
const ArticleComponent = React.memo(({ data }) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (tree === null)
|
|
314
|
-
return null;
|
|
315
|
-
return (React.createElement(Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
316
|
-
React.createElement(Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
317
|
-
React.createElement(MarkdownViewer, { markdown: tree })),
|
|
318
|
-
React.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
223
|
+
return (React.createElement(Box, { className: "sl-elements-article" },
|
|
224
|
+
React.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
319
225
|
});
|
|
320
226
|
const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
321
227
|
|
|
@@ -1610,9 +1516,9 @@ const bodyFormatMap = {
|
|
|
1610
1516
|
text: ['raw'],
|
|
1611
1517
|
};
|
|
1612
1518
|
const regex = {
|
|
1613
|
-
image: /image\/(
|
|
1614
|
-
json: /application\/(
|
|
1615
|
-
xml: /(text|application)\/(
|
|
1519
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1520
|
+
json: /application\/(.?)*json/,
|
|
1521
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1616
1522
|
text: /text\/.*/,
|
|
1617
1523
|
};
|
|
1618
1524
|
function getResponseType(contentType) {
|
|
@@ -2177,7 +2083,7 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2177
2083
|
const hasBadges = isDeprecated || isInternal;
|
|
2178
2084
|
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
|
|
2179
2085
|
React.createElement(HStack, { spacing: 5 },
|
|
2180
|
-
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading
|
|
2086
|
+
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
|
|
2181
2087
|
React.createElement(HStack, { spacing: 2 },
|
|
2182
2088
|
isDeprecated && React.createElement(DeprecatedBadge, null),
|
|
2183
2089
|
isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
|
|
@@ -2301,7 +2207,7 @@ const HttpServiceComponent = React.memo(({ data, location = {}, layoutOptions, e
|
|
|
2301
2207
|
const query = new URLSearchParams(search);
|
|
2302
2208
|
return (React.createElement(Box, { mb: 10 },
|
|
2303
2209
|
data.name && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2304
|
-
React.createElement(Heading
|
|
2210
|
+
React.createElement(Heading, { size: 1, mb: 4, fontWeight: "semibold" }, data.name),
|
|
2305
2211
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps)))),
|
|
2306
2212
|
data.version && (React.createElement(Box, { mb: 5 },
|
|
2307
2213
|
React.createElement(VersionBadge, { value: data.version }))),
|
|
@@ -2332,7 +2238,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2332
2238
|
const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
|
|
2333
2239
|
const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2334
2240
|
React.createElement(HStack, { spacing: 5 },
|
|
2335
|
-
title && (React.createElement(Heading
|
|
2241
|
+
title && (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, title)),
|
|
2336
2242
|
React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
|
|
2337
2243
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
|
|
2338
2244
|
const description = (React.createElement(VStack, { spacing: 10 },
|
|
@@ -2347,14 +2253,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2347
2253
|
const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2348
2254
|
|
|
2349
2255
|
const Docs = React.memo((_a) => {
|
|
2350
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2256
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2351
2257
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2352
2258
|
if (!parsedNode) {
|
|
2353
2259
|
return null;
|
|
2354
2260
|
}
|
|
2355
2261
|
const parsedDocs = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2356
2262
|
if (useNodeForRefResolving) {
|
|
2357
|
-
return React.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2263
|
+
return (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2358
2264
|
}
|
|
2359
2265
|
return parsedDocs;
|
|
2360
2266
|
});
|
|
@@ -2389,7 +2295,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
|
|
|
2389
2295
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2390
2296
|
minWidth: `${sidebarWidth}px`,
|
|
2391
2297
|
} }, sidebar),
|
|
2392
|
-
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2298
|
+
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full", overflowY: "auto" },
|
|
2393
2299
|
React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2394
2300
|
});
|
|
2395
2301
|
|
|
@@ -2418,7 +2324,7 @@ function useParsedValue(value) {
|
|
|
2418
2324
|
let parsedValue = value;
|
|
2419
2325
|
if (typeof value === 'string') {
|
|
2420
2326
|
try {
|
|
2421
|
-
parsedValue = parse
|
|
2327
|
+
parsedValue = parse(value);
|
|
2422
2328
|
}
|
|
2423
2329
|
catch (error) {
|
|
2424
2330
|
}
|
|
@@ -2444,8 +2350,8 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
|
|
|
2444
2350
|
React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
|
|
2445
2351
|
};
|
|
2446
2352
|
const CodeComponent = props => {
|
|
2447
|
-
const { title, jsonSchema, http, children } = props;
|
|
2448
|
-
const value = String(Array.isArray(children) ? children[0] : children);
|
|
2353
|
+
const { title, jsonSchema, http, resolved, children } = props;
|
|
2354
|
+
const value = resolved || String(Array.isArray(children) ? children[0] : children);
|
|
2449
2355
|
const parsedValue = useParsedValue(value);
|
|
2450
2356
|
if (jsonSchema) {
|
|
2451
2357
|
if (!isJSONSchema(parsedValue)) {
|
|
@@ -2512,7 +2418,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2512
2418
|
};
|
|
2513
2419
|
|
|
2514
2420
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2515
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2421
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2422
|
+
const href = to || _href;
|
|
2516
2423
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2517
2424
|
if (isExternal) {
|
|
2518
2425
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2691,7 +2598,7 @@ const Version = ({ value }) => {
|
|
|
2691
2598
|
const NonIdealState = ({ description, icon, title }) => {
|
|
2692
2599
|
return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
|
|
2693
2600
|
React.createElement(Box, { as: Icon, icon: icon || faExclamationTriangle, color: "light", fontSize: "6xl", mb: 4 }),
|
|
2694
|
-
React.createElement(Heading
|
|
2601
|
+
React.createElement(Heading, { size: 4, mb: 4 }, title),
|
|
2695
2602
|
React.createElement(Text, null, description)));
|
|
2696
2603
|
};
|
|
2697
2604
|
|
|
@@ -2758,7 +2665,7 @@ function withRouter(WrappedComponent) {
|
|
|
2758
2665
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2759
2666
|
return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2760
2667
|
React.createElement(Route, { path: "/" },
|
|
2761
|
-
React.createElement(MarkdownComponentsProvider, { value: {
|
|
2668
|
+
React.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2762
2669
|
React.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2763
2670
|
};
|
|
2764
2671
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoplight/elements-core",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.11",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"web-components.min.js",
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"@stoplight/json-schema-ref-parser": "^9.0.5",
|
|
30
30
|
"@stoplight/json-schema-sampler": "0.2.2",
|
|
31
31
|
"@stoplight/json-schema-viewer": "^4.5.0",
|
|
32
|
-
"@stoplight/markdown": "^
|
|
33
|
-
"@stoplight/markdown-viewer": "^5.3.2",
|
|
32
|
+
"@stoplight/markdown-viewer": "^5.4.2",
|
|
34
33
|
"@stoplight/mosaic": "^1.15.2",
|
|
35
34
|
"@stoplight/mosaic-code-editor": "^1.15.2",
|
|
36
35
|
"@stoplight/mosaic-code-viewer": "^1.15.2",
|
|
@@ -49,7 +48,6 @@
|
|
|
49
48
|
"react-router-dom": "^5.2.0",
|
|
50
49
|
"react-router-hash-link": "^2.1.0",
|
|
51
50
|
"tslib": "^2.1.0",
|
|
52
|
-
"unist-util-select": "^3.0.1",
|
|
53
51
|
"urijs": "^1.19.6",
|
|
54
52
|
"util": "^0.12.4",
|
|
55
53
|
"xml-formatter": "^2.4.0"
|
package/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { IHttpOperation, IHttpService, NodeType } from '@stoplight/types';
|
|
3
3
|
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
4
4
|
export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
5
5
|
export declare type ParsedNode = {
|
|
6
6
|
type: NodeType.Article;
|
|
7
|
-
data:
|
|
7
|
+
data: IMarkdownViewerProps['markdown'];
|
|
8
8
|
} | {
|
|
9
9
|
type: NodeType.HttpOperation;
|
|
10
10
|
data: IHttpOperation;
|
|
@@ -105,15 +105,3 @@ export declare type ParamField = {
|
|
|
105
105
|
description: string;
|
|
106
106
|
example: string;
|
|
107
107
|
};
|
|
108
|
-
export interface IArticleHeading {
|
|
109
|
-
id: string;
|
|
110
|
-
title: string;
|
|
111
|
-
depth: number;
|
|
112
|
-
}
|
|
113
|
-
export interface IArticleHeadings {
|
|
114
|
-
headings: IArticleHeading[];
|
|
115
|
-
title?: string;
|
|
116
|
-
className?: string;
|
|
117
|
-
minimal?: boolean;
|
|
118
|
-
maxWidth?: number;
|
|
119
|
-
}
|
package/utils/guards.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { IHttpOperation, IHttpService } from '@stoplight/types';
|
|
3
3
|
import { JSONSchema7 } from 'json-schema';
|
|
4
|
-
export declare function isSMDASTRoot(maybeAst: unknown): maybeAst is
|
|
4
|
+
export declare function isSMDASTRoot(maybeAst: unknown): maybeAst is IMarkdownViewerProps['markdown'];
|
|
5
5
|
export declare function isJSONSchema(maybeSchema: unknown): maybeSchema is JSONSchema7;
|
|
6
6
|
export declare function isHttpService(maybeHttpService: unknown): maybeHttpService is IHttpService;
|
|
7
7
|
export declare function isHttpOperation(maybeHttpOperation: unknown): maybeHttpOperation is IHttpOperation;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function useLocationHash(): string | false;
|