@stoplight/elements-core 8.5.1 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/MarkdownViewer/CustomComponents/ScrollToHashElement.d.ts +8 -0
- package/hoc/withRouter.d.ts +3 -1
- package/index.d.ts +3 -1
- package/index.esm.js +93 -20
- package/index.js +94 -18
- package/index.mjs +93 -20
- package/package.json +2 -3
- package/utils/string.d.ts +1 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ScrollToHashElementProps {
|
|
2
|
+
initialBehavior?: ScrollBehavior;
|
|
3
|
+
behavior?: ScrollBehavior;
|
|
4
|
+
inline?: ScrollLogicalPosition;
|
|
5
|
+
block?: ScrollLogicalPosition;
|
|
6
|
+
}
|
|
7
|
+
export declare const ScrollToHashElement: ({ behavior, initialBehavior, inline, block, }: ScrollToHashElementProps) => null;
|
|
8
|
+
export {};
|
package/hoc/withRouter.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { RoutingProps } from '../types';
|
|
3
|
-
export declare function withRouter<P extends RoutingProps>(WrappedComponent: React.ComponentType<P
|
|
3
|
+
export declare function withRouter<P extends RoutingProps>(WrappedComponent: React.ComponentType<P & {
|
|
4
|
+
outerRouter?: boolean;
|
|
5
|
+
}>): React.FC<P>;
|
package/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { Logo } from './components/Logo';
|
|
|
8
8
|
export { DefaultSMDComponents } from './components/MarkdownViewer/CustomComponents/CodeComponent';
|
|
9
9
|
export { CustomComponentMapping, MarkdownComponentsProvider, } from './components/MarkdownViewer/CustomComponents/Provider';
|
|
10
10
|
export { ReactRouterMarkdownLink } from './components/MarkdownViewer/CustomComponents/ReactRouterLink';
|
|
11
|
+
export { ScrollToHashElement } from './components/MarkdownViewer/CustomComponents/ScrollToHashElement';
|
|
11
12
|
export { NonIdealState } from './components/NonIdealState';
|
|
12
13
|
export { PoweredByLink } from './components/PoweredByLink';
|
|
13
14
|
export { TableOfContents } from './components/TableOfContents';
|
|
@@ -33,5 +34,6 @@ export { Divider, Group, ITableOfContentsTree, Item, ParsedNode, RoutingProps, T
|
|
|
33
34
|
export { isHttpOperation, isHttpService, isHttpWebhookOperation } from './utils/guards';
|
|
34
35
|
export { ReferenceResolver } from './utils/ref-resolving/ReferenceResolver';
|
|
35
36
|
export { createResolvedObject } from './utils/ref-resolving/resolvedObject';
|
|
36
|
-
export { slugify } from './utils/string';
|
|
37
|
+
export { slugify, resolveRelativeLink } from './utils/string';
|
|
37
38
|
export { createElementClass } from './web-components/createElementClass';
|
|
39
|
+
export { resolveUrl } from './utils/http-spec/IServer';
|
package/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest, __awaiter } from 'tslib';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { useContext, memo, useMemo, useState, useEffect } from 'react';
|
|
3
|
+
import React__default, { useContext, memo, useMemo, useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
4
4
|
import { convertToJsonSchema } from '@stoplight/http-spec/oas';
|
|
5
5
|
import { resolveInlineRef, hasRef, isPlainObject as isPlainObject$1, safeParse, safeStringify } from '@stoplight/json';
|
|
6
6
|
import isArray from 'lodash/isArray.js';
|
|
@@ -10,7 +10,7 @@ import { parse } from '@stoplight/yaml';
|
|
|
10
10
|
import { isArray as isArray$1, Box, useBreakpoints, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading as LinkHeading$1, NodeAnnotation, Callout, useModalState, Modal, ListBox, ListBoxItem, TabList, Tab, Tabs, TabPanels, TabPanel, Heading, useClipboard, Drawer, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
11
11
|
import isObject from 'lodash/isObject.js';
|
|
12
12
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
|
-
import { useLocation, Link as Link$1, BrowserRouter, MemoryRouter, HashRouter,
|
|
13
|
+
import { useLocation, Link as Link$1, BrowserRouter, MemoryRouter, HashRouter, useInRouterContext, Routes, Route } from 'react-router-dom';
|
|
14
14
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
15
15
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
16
16
|
import cn from 'classnames';
|
|
@@ -51,8 +51,8 @@ import keys from 'lodash/keys.js';
|
|
|
51
51
|
import sortBy from 'lodash/sortBy.js';
|
|
52
52
|
import isNil from 'lodash/isNil.js';
|
|
53
53
|
import omitBy from 'lodash/omitBy.js';
|
|
54
|
-
import { HashLink } from 'react-router-hash-link';
|
|
55
54
|
import { QueryClient, useQueryClient, QueryClientProvider } from 'react-query';
|
|
55
|
+
import { StaticRouter } from 'react-router-dom/server.js';
|
|
56
56
|
import $RefParser from '@stoplight/json-schema-ref-parser';
|
|
57
57
|
import * as PropTypes from 'prop-types';
|
|
58
58
|
import isEqual from 'lodash/isEqual.js';
|
|
@@ -1105,6 +1105,9 @@ function slugify(name) {
|
|
|
1105
1105
|
.replace(/^-/, '')
|
|
1106
1106
|
.replace(/-$/, '');
|
|
1107
1107
|
}
|
|
1108
|
+
const resolveRelativeLink = (slug) => {
|
|
1109
|
+
return slug ? slug.replace(/^\//, '') : '.';
|
|
1110
|
+
};
|
|
1108
1111
|
|
|
1109
1112
|
const isApiKeySecurityScheme = (maybeIApiKey) => isObject(maybeIApiKey) && maybeIApiKey.type === 'apiKey';
|
|
1110
1113
|
const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject(maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
|
|
@@ -3501,7 +3504,6 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3501
3504
|
const container = React.useRef(null);
|
|
3502
3505
|
const child = React.useRef(null);
|
|
3503
3506
|
const firstRender = useFirstRender();
|
|
3504
|
-
const makeSlugAbsoluteRoute = useRouterType() == 'hash';
|
|
3505
3507
|
React.useEffect(() => {
|
|
3506
3508
|
setTimeout(() => {
|
|
3507
3509
|
const scrollPosition = firstRender ? 'center' : 'nearest';
|
|
@@ -3522,7 +3524,7 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3522
3524
|
if (isDivider(item)) {
|
|
3523
3525
|
return React.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3524
3526
|
}
|
|
3525
|
-
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3527
|
+
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3526
3528
|
}))))));
|
|
3527
3529
|
});
|
|
3528
3530
|
TableOfContents.displayName = 'TableOfContents';
|
|
@@ -3530,23 +3532,23 @@ const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
|
|
|
3530
3532
|
return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3531
3533
|
});
|
|
3532
3534
|
Divider.displayName = 'Divider';
|
|
3533
|
-
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3535
|
+
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3534
3536
|
if (isExternalLink(item)) {
|
|
3535
3537
|
return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
3536
3538
|
React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, depth: depth, title: item.title, meta: React.createElement(Box, { as: Icon, icon: ['fas', 'external-link'] }) })));
|
|
3537
3539
|
}
|
|
3538
3540
|
else if (isGroup(item) || isNodeGroup(item)) {
|
|
3539
|
-
return (React.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3541
|
+
return (React.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3540
3542
|
}
|
|
3541
3543
|
else if (isNode(item)) {
|
|
3542
|
-
return (React.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode,
|
|
3544
|
+
return (React.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode, item: item, onLinkClick: onLinkClick, meta: item.meta ? (React.createElement(Box, { color: NODE_META_COLOR[item.meta], textTransform: "uppercase", fontWeight: "medium" }, item.meta)) : (NODE_TYPE_META_ICON[item.type] && (React.createElement(Flex, { alignItems: "center" },
|
|
3543
3545
|
item.version && React.createElement(Version, { value: item.version }),
|
|
3544
3546
|
item.type !== 'model' && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_META_ICON[item.type] }))))) }));
|
|
3545
3547
|
}
|
|
3546
3548
|
return null;
|
|
3547
3549
|
});
|
|
3548
3550
|
GroupItem.displayName = 'GroupItem';
|
|
3549
|
-
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3551
|
+
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3550
3552
|
const activeId = React.useContext(ActiveIdContext);
|
|
3551
3553
|
const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3552
3554
|
const hasActive = !!activeId && hasActiveItem(item.items, activeId);
|
|
@@ -3574,7 +3576,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
|
|
|
3574
3576
|
const showAsActive = hasActive && !isOpen;
|
|
3575
3577
|
let elem;
|
|
3576
3578
|
if (isNodeGroup(item)) {
|
|
3577
|
-
elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3579
|
+
elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3578
3580
|
}
|
|
3579
3581
|
else {
|
|
3580
3582
|
elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
|
|
@@ -3584,7 +3586,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
|
|
|
3584
3586
|
elem,
|
|
3585
3587
|
isOpen &&
|
|
3586
3588
|
item.items.map((groupItem, key) => {
|
|
3587
|
-
return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3589
|
+
return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3588
3590
|
})));
|
|
3589
3591
|
});
|
|
3590
3592
|
Group.displayName = 'Group';
|
|
@@ -3598,7 +3600,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
|
|
|
3598
3600
|
React.createElement(Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
|
|
3599
3601
|
});
|
|
3600
3602
|
Item.displayName = 'Item';
|
|
3601
|
-
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
3603
|
+
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3602
3604
|
const activeId = React.useContext(ActiveIdContext);
|
|
3603
3605
|
const isActive = activeId === item.slug || activeId === item.id;
|
|
3604
3606
|
const LinkComponent = React.useContext(LinkContext);
|
|
@@ -3614,7 +3616,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3614
3616
|
onClick(e, isActive ? undefined : true);
|
|
3615
3617
|
}
|
|
3616
3618
|
};
|
|
3617
|
-
return (React.createElement(Box, { as: LinkComponent, to:
|
|
3619
|
+
return (React.createElement(Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3618
3620
|
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3619
3621
|
});
|
|
3620
3622
|
Node.displayName = 'Node';
|
|
@@ -3638,7 +3640,8 @@ const MobileTopNav = ({ name, logo, tree, pathname, onTocClick, }) => {
|
|
|
3638
3640
|
React.createElement(Flex, { justifyContent: "end" },
|
|
3639
3641
|
React.createElement(Button, { className: "sl-mr-4 sl-mt-2", onPress: () => setIsSidebarOpen(false), appearance: "minimal", justifySelf: "end" },
|
|
3640
3642
|
React.createElement(Icon, { size: "lg", icon: faX }))),
|
|
3641
|
-
React.createElement(
|
|
3643
|
+
React.createElement(Box, { tabIndex: -1 },
|
|
3644
|
+
React.createElement(Sidebar, { name: name, logo: logo, tree: tree, pathname: pathname, onTocClick: handleTocClick, isInResponsiveMode: true })))));
|
|
3642
3645
|
};
|
|
3643
3646
|
const NavHeading = ({ heading }) => (React.createElement(Flex, { flex: 1, "data-test": "mobile-project-top-nav", style: { minWidth: 0 } },
|
|
3644
3647
|
React.createElement(Box, { fontSize: "xl", fontWeight: "semibold", whitespace: "nowrap", textOverflow: "overflow-ellipsis", overflowX: "hidden", overflowY: "hidden", w: "full", textAlign: "center" }, heading)));
|
|
@@ -3878,7 +3881,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3878
3881
|
if (isExternal) {
|
|
3879
3882
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3880
3883
|
}
|
|
3881
|
-
return (React__default.createElement(
|
|
3884
|
+
return (React__default.createElement("a", { href: href, title: title }, children));
|
|
3885
|
+
};
|
|
3886
|
+
|
|
3887
|
+
const ScrollToHashElement = ({ behavior = 'auto', initialBehavior = 'auto', inline = 'nearest', block = 'start', }) => {
|
|
3888
|
+
const [hash, setHash] = useState(window.location.hash);
|
|
3889
|
+
const [count, setCount] = useState(0);
|
|
3890
|
+
const originalListeners = useRef({});
|
|
3891
|
+
const [firstRun, setFirstRun] = useState(true);
|
|
3892
|
+
useEffect(() => setFirstRun(false), []);
|
|
3893
|
+
useEffect(() => {
|
|
3894
|
+
const handleLocationChange = () => {
|
|
3895
|
+
setHash(window.location.hash);
|
|
3896
|
+
setCount((count) => count + 1);
|
|
3897
|
+
};
|
|
3898
|
+
const onPopState = () => {
|
|
3899
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3900
|
+
};
|
|
3901
|
+
const addWindowListeners = () => {
|
|
3902
|
+
originalListeners.current.pushState = window.history.pushState;
|
|
3903
|
+
originalListeners.current.replaceState = window.history.replaceState;
|
|
3904
|
+
window.history.pushState = function (...args) {
|
|
3905
|
+
const result = originalListeners.current.pushState.apply(this, args);
|
|
3906
|
+
window.dispatchEvent(new Event('pushstate'));
|
|
3907
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3908
|
+
return result;
|
|
3909
|
+
};
|
|
3910
|
+
window.history.replaceState = function (...args) {
|
|
3911
|
+
const result = originalListeners.current.replaceState.apply(this, args);
|
|
3912
|
+
window.dispatchEvent(new Event('replacestate'));
|
|
3913
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3914
|
+
return result;
|
|
3915
|
+
};
|
|
3916
|
+
window.addEventListener('popstate', onPopState);
|
|
3917
|
+
window.addEventListener('locationchange', handleLocationChange);
|
|
3918
|
+
};
|
|
3919
|
+
const removeWindowListeners = () => {
|
|
3920
|
+
window.history.pushState = originalListeners.current.pushState;
|
|
3921
|
+
window.history.replaceState = originalListeners.current.replaceState;
|
|
3922
|
+
window.removeEventListener('popstate', onPopState);
|
|
3923
|
+
window.removeEventListener('locationchange', handleLocationChange);
|
|
3924
|
+
};
|
|
3925
|
+
addWindowListeners();
|
|
3926
|
+
return removeWindowListeners;
|
|
3927
|
+
}, []);
|
|
3928
|
+
useLayoutEffect(() => {
|
|
3929
|
+
const removeHashCharacter = (str) => {
|
|
3930
|
+
return str.slice(1);
|
|
3931
|
+
};
|
|
3932
|
+
if (hash) {
|
|
3933
|
+
const element = document.getElementById(removeHashCharacter(hash));
|
|
3934
|
+
if (element) {
|
|
3935
|
+
element.scrollIntoView({
|
|
3936
|
+
behavior: firstRun ? initialBehavior : behavior,
|
|
3937
|
+
inline: inline,
|
|
3938
|
+
block: block,
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
}, [hash, count, firstRun]);
|
|
3943
|
+
return null;
|
|
3882
3944
|
};
|
|
3883
3945
|
|
|
3884
3946
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3958,18 +4020,29 @@ const components = {
|
|
|
3958
4020
|
return React.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3959
4021
|
},
|
|
3960
4022
|
};
|
|
4023
|
+
const InternalRoutes = ({ children }) => {
|
|
4024
|
+
return (React.createElement(Routes, null,
|
|
4025
|
+
React.createElement(Route, { path: "/*", element: React.createElement(MarkdownComponentsProvider, { value: components },
|
|
4026
|
+
React.createElement(ScrollToHashElement, null),
|
|
4027
|
+
children) })));
|
|
4028
|
+
};
|
|
3961
4029
|
function withRouter(WrappedComponent) {
|
|
3962
4030
|
const WithRouter = (props) => {
|
|
3963
4031
|
var _a, _b, _c;
|
|
4032
|
+
const outerRouter = useInRouterContext();
|
|
3964
4033
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3965
4034
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3966
4035
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3967
4036
|
const { Router, routerProps } = useRouter(routerType, basePath, staticRouterPath);
|
|
4037
|
+
if (!outerRouter) {
|
|
4038
|
+
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
4039
|
+
React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
4040
|
+
React.createElement(InternalRoutes, null,
|
|
4041
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: false }))))));
|
|
4042
|
+
}
|
|
3968
4043
|
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3969
|
-
React.createElement(
|
|
3970
|
-
React.createElement(
|
|
3971
|
-
React.createElement(MarkdownComponentsProvider, { value: components },
|
|
3972
|
-
React.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4044
|
+
React.createElement(InternalRoutes, null,
|
|
4045
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3973
4046
|
};
|
|
3974
4047
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3975
4048
|
return WithRouter;
|
|
@@ -4139,4 +4212,4 @@ const createElementClass = (Component, propDescriptors) => {
|
|
|
4139
4212
|
};
|
|
4140
4213
|
};
|
|
4141
4214
|
|
|
4142
|
-
export { DeprecatedBadge, Docs, ElementsOptionsProvider, ExportButton, HttpMethodColors, InlineRefResolverProvider, LinkHeading, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, ResponsiveSidebarLayout, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useResponsiveLayout, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|
|
4215
|
+
export { DeprecatedBadge, Docs, ElementsOptionsProvider, ExportButton, HttpMethodColors, InlineRefResolverProvider, LinkHeading, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, ResponsiveSidebarLayout, RouterTypeContext, ScrollToHashElement, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, resolveRelativeLink, resolveUrl, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useResponsiveLayout, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|
package/index.js
CHANGED
|
@@ -51,8 +51,8 @@ var keys = require('lodash/keys.js');
|
|
|
51
51
|
var sortBy = require('lodash/sortBy.js');
|
|
52
52
|
var isNil = require('lodash/isNil.js');
|
|
53
53
|
var omitBy = require('lodash/omitBy.js');
|
|
54
|
-
var reactRouterHashLink = require('react-router-hash-link');
|
|
55
54
|
var reactQuery = require('react-query');
|
|
55
|
+
var server_js = require('react-router-dom/server.js');
|
|
56
56
|
var $RefParser = require('@stoplight/json-schema-ref-parser');
|
|
57
57
|
var PropTypes = require('prop-types');
|
|
58
58
|
var isEqual = require('lodash/isEqual.js');
|
|
@@ -1127,6 +1127,9 @@ function slugify(name) {
|
|
|
1127
1127
|
.replace(/^-/, '')
|
|
1128
1128
|
.replace(/-$/, '');
|
|
1129
1129
|
}
|
|
1130
|
+
const resolveRelativeLink = (slug) => {
|
|
1131
|
+
return slug ? slug.replace(/^\//, '') : '.';
|
|
1132
|
+
};
|
|
1130
1133
|
|
|
1131
1134
|
const isApiKeySecurityScheme = (maybeIApiKey) => isObject(maybeIApiKey) && maybeIApiKey.type === 'apiKey';
|
|
1132
1135
|
const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject(maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
|
|
@@ -3523,7 +3526,6 @@ const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthO
|
|
|
3523
3526
|
const container = React__namespace.useRef(null);
|
|
3524
3527
|
const child = React__namespace.useRef(null);
|
|
3525
3528
|
const firstRender = useFirstRender();
|
|
3526
|
-
const makeSlugAbsoluteRoute = useRouterType() == 'hash';
|
|
3527
3529
|
React__namespace.useEffect(() => {
|
|
3528
3530
|
setTimeout(() => {
|
|
3529
3531
|
const scrollPosition = firstRender ? 'center' : 'nearest';
|
|
@@ -3544,7 +3546,7 @@ const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthO
|
|
|
3544
3546
|
if (isDivider(item)) {
|
|
3545
3547
|
return React__namespace.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3546
3548
|
}
|
|
3547
|
-
return (React__namespace.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3549
|
+
return (React__namespace.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3548
3550
|
}))))));
|
|
3549
3551
|
});
|
|
3550
3552
|
TableOfContents.displayName = 'TableOfContents';
|
|
@@ -3552,23 +3554,23 @@ const Divider = React__namespace.memo(({ item, isInResponsiveMode = false }) =>
|
|
|
3552
3554
|
return (React__namespace.createElement(mosaic.Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3553
3555
|
});
|
|
3554
3556
|
Divider.displayName = 'Divider';
|
|
3555
|
-
const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3557
|
+
const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3556
3558
|
if (isExternalLink(item)) {
|
|
3557
3559
|
return (React__namespace.createElement(mosaic.Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
3558
3560
|
React__namespace.createElement(Item, { isInResponsiveMode: isInResponsiveMode, depth: depth, title: item.title, meta: React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: ['fas', 'external-link'] }) })));
|
|
3559
3561
|
}
|
|
3560
3562
|
else if (isGroup(item) || isNodeGroup(item)) {
|
|
3561
|
-
return (React__namespace.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3563
|
+
return (React__namespace.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3562
3564
|
}
|
|
3563
3565
|
else if (isNode(item)) {
|
|
3564
|
-
return (React__namespace.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode,
|
|
3566
|
+
return (React__namespace.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode, item: item, onLinkClick: onLinkClick, meta: item.meta ? (React__namespace.createElement(mosaic.Box, { color: NODE_META_COLOR[item.meta], textTransform: "uppercase", fontWeight: "medium" }, item.meta)) : (NODE_TYPE_META_ICON[item.type] && (React__namespace.createElement(mosaic.Flex, { alignItems: "center" },
|
|
3565
3567
|
item.version && React__namespace.createElement(Version, { value: item.version }),
|
|
3566
3568
|
item.type !== 'model' && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_META_ICON[item.type] }))))) }));
|
|
3567
3569
|
}
|
|
3568
3570
|
return null;
|
|
3569
3571
|
});
|
|
3570
3572
|
GroupItem.displayName = 'GroupItem';
|
|
3571
|
-
const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3573
|
+
const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3572
3574
|
const activeId = React__namespace.useContext(ActiveIdContext);
|
|
3573
3575
|
const [isOpen, setIsOpen] = React__namespace.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3574
3576
|
const hasActive = !!activeId && hasActiveItem(item.items, activeId);
|
|
@@ -3596,7 +3598,7 @@ const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInR
|
|
|
3596
3598
|
const showAsActive = hasActive && !isOpen;
|
|
3597
3599
|
let elem;
|
|
3598
3600
|
if (isNodeGroup(item)) {
|
|
3599
|
-
elem = (React__namespace.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3601
|
+
elem = (React__namespace.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3600
3602
|
}
|
|
3601
3603
|
else {
|
|
3602
3604
|
elem = (React__namespace.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
|
|
@@ -3606,7 +3608,7 @@ const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInR
|
|
|
3606
3608
|
elem,
|
|
3607
3609
|
isOpen &&
|
|
3608
3610
|
item.items.map((groupItem, key) => {
|
|
3609
|
-
return (React__namespace.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3611
|
+
return (React__namespace.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3610
3612
|
})));
|
|
3611
3613
|
});
|
|
3612
3614
|
Group.displayName = 'Group';
|
|
@@ -3620,7 +3622,7 @@ const Item = React__namespace.memo(({ depth, isActive, id, title, meta, icon, is
|
|
|
3620
3622
|
React__namespace.createElement(mosaic.Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
|
|
3621
3623
|
});
|
|
3622
3624
|
Item.displayName = 'Item';
|
|
3623
|
-
const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
3625
|
+
const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3624
3626
|
const activeId = React__namespace.useContext(ActiveIdContext);
|
|
3625
3627
|
const isActive = activeId === item.slug || activeId === item.id;
|
|
3626
3628
|
const LinkComponent = React__namespace.useContext(LinkContext);
|
|
@@ -3636,7 +3638,7 @@ const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInRespo
|
|
|
3636
3638
|
onClick(e, isActive ? undefined : true);
|
|
3637
3639
|
}
|
|
3638
3640
|
};
|
|
3639
|
-
return (React__namespace.createElement(mosaic.Box, { as: LinkComponent, to:
|
|
3641
|
+
return (React__namespace.createElement(mosaic.Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3640
3642
|
React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3641
3643
|
});
|
|
3642
3644
|
Node.displayName = 'Node';
|
|
@@ -3660,7 +3662,8 @@ const MobileTopNav = ({ name, logo, tree, pathname, onTocClick, }) => {
|
|
|
3660
3662
|
React__namespace.createElement(mosaic.Flex, { justifyContent: "end" },
|
|
3661
3663
|
React__namespace.createElement(mosaic.Button, { className: "sl-mr-4 sl-mt-2", onPress: () => setIsSidebarOpen(false), appearance: "minimal", justifySelf: "end" },
|
|
3662
3664
|
React__namespace.createElement(mosaic.Icon, { size: "lg", icon: faX }))),
|
|
3663
|
-
React__namespace.createElement(
|
|
3665
|
+
React__namespace.createElement(mosaic.Box, { tabIndex: -1 },
|
|
3666
|
+
React__namespace.createElement(Sidebar, { name: name, logo: logo, tree: tree, pathname: pathname, onTocClick: handleTocClick, isInResponsiveMode: true })))));
|
|
3664
3667
|
};
|
|
3665
3668
|
const NavHeading = ({ heading }) => (React__namespace.createElement(mosaic.Flex, { flex: 1, "data-test": "mobile-project-top-nav", style: { minWidth: 0 } },
|
|
3666
3669
|
React__namespace.createElement(mosaic.Box, { fontSize: "xl", fontWeight: "semibold", whitespace: "nowrap", textOverflow: "overflow-ellipsis", overflowX: "hidden", overflowY: "hidden", w: "full", textAlign: "center" }, heading)));
|
|
@@ -3900,7 +3903,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3900
3903
|
if (isExternal) {
|
|
3901
3904
|
return (React.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3902
3905
|
}
|
|
3903
|
-
return (React.createElement(
|
|
3906
|
+
return (React.createElement("a", { href: href, title: title }, children));
|
|
3907
|
+
};
|
|
3908
|
+
|
|
3909
|
+
const ScrollToHashElement = ({ behavior = 'auto', initialBehavior = 'auto', inline = 'nearest', block = 'start', }) => {
|
|
3910
|
+
const [hash, setHash] = React.useState(window.location.hash);
|
|
3911
|
+
const [count, setCount] = React.useState(0);
|
|
3912
|
+
const originalListeners = React.useRef({});
|
|
3913
|
+
const [firstRun, setFirstRun] = React.useState(true);
|
|
3914
|
+
React.useEffect(() => setFirstRun(false), []);
|
|
3915
|
+
React.useEffect(() => {
|
|
3916
|
+
const handleLocationChange = () => {
|
|
3917
|
+
setHash(window.location.hash);
|
|
3918
|
+
setCount((count) => count + 1);
|
|
3919
|
+
};
|
|
3920
|
+
const onPopState = () => {
|
|
3921
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3922
|
+
};
|
|
3923
|
+
const addWindowListeners = () => {
|
|
3924
|
+
originalListeners.current.pushState = window.history.pushState;
|
|
3925
|
+
originalListeners.current.replaceState = window.history.replaceState;
|
|
3926
|
+
window.history.pushState = function (...args) {
|
|
3927
|
+
const result = originalListeners.current.pushState.apply(this, args);
|
|
3928
|
+
window.dispatchEvent(new Event('pushstate'));
|
|
3929
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3930
|
+
return result;
|
|
3931
|
+
};
|
|
3932
|
+
window.history.replaceState = function (...args) {
|
|
3933
|
+
const result = originalListeners.current.replaceState.apply(this, args);
|
|
3934
|
+
window.dispatchEvent(new Event('replacestate'));
|
|
3935
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3936
|
+
return result;
|
|
3937
|
+
};
|
|
3938
|
+
window.addEventListener('popstate', onPopState);
|
|
3939
|
+
window.addEventListener('locationchange', handleLocationChange);
|
|
3940
|
+
};
|
|
3941
|
+
const removeWindowListeners = () => {
|
|
3942
|
+
window.history.pushState = originalListeners.current.pushState;
|
|
3943
|
+
window.history.replaceState = originalListeners.current.replaceState;
|
|
3944
|
+
window.removeEventListener('popstate', onPopState);
|
|
3945
|
+
window.removeEventListener('locationchange', handleLocationChange);
|
|
3946
|
+
};
|
|
3947
|
+
addWindowListeners();
|
|
3948
|
+
return removeWindowListeners;
|
|
3949
|
+
}, []);
|
|
3950
|
+
React.useLayoutEffect(() => {
|
|
3951
|
+
const removeHashCharacter = (str) => {
|
|
3952
|
+
return str.slice(1);
|
|
3953
|
+
};
|
|
3954
|
+
if (hash) {
|
|
3955
|
+
const element = document.getElementById(removeHashCharacter(hash));
|
|
3956
|
+
if (element) {
|
|
3957
|
+
element.scrollIntoView({
|
|
3958
|
+
behavior: firstRun ? initialBehavior : behavior,
|
|
3959
|
+
inline: inline,
|
|
3960
|
+
block: block,
|
|
3961
|
+
});
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
}, [hash, count, firstRun]);
|
|
3965
|
+
return null;
|
|
3904
3966
|
};
|
|
3905
3967
|
|
|
3906
3968
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3954,7 +4016,7 @@ const RouterComponent = {
|
|
|
3954
4016
|
history: reactRouterDom.BrowserRouter,
|
|
3955
4017
|
memory: reactRouterDom.MemoryRouter,
|
|
3956
4018
|
hash: reactRouterDom.HashRouter,
|
|
3957
|
-
static:
|
|
4019
|
+
static: server_js.StaticRouter,
|
|
3958
4020
|
};
|
|
3959
4021
|
const useRouter = (router, basePath, staticRouterPath) => {
|
|
3960
4022
|
const Router = RouterComponent[router];
|
|
@@ -3980,18 +4042,29 @@ const components = {
|
|
|
3980
4042
|
return React__namespace.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3981
4043
|
},
|
|
3982
4044
|
};
|
|
4045
|
+
const InternalRoutes = ({ children }) => {
|
|
4046
|
+
return (React__namespace.createElement(reactRouterDom.Routes, null,
|
|
4047
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/*", element: React__namespace.createElement(MarkdownComponentsProvider, { value: components },
|
|
4048
|
+
React__namespace.createElement(ScrollToHashElement, null),
|
|
4049
|
+
children) })));
|
|
4050
|
+
};
|
|
3983
4051
|
function withRouter(WrappedComponent) {
|
|
3984
4052
|
const WithRouter = (props) => {
|
|
3985
4053
|
var _a, _b, _c;
|
|
4054
|
+
const outerRouter = reactRouterDom.useInRouterContext();
|
|
3986
4055
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3987
4056
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3988
4057
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3989
4058
|
const { Router, routerProps } = useRouter(routerType, basePath, staticRouterPath);
|
|
4059
|
+
if (!outerRouter) {
|
|
4060
|
+
return (React__namespace.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
4061
|
+
React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
4062
|
+
React__namespace.createElement(InternalRoutes, null,
|
|
4063
|
+
React__namespace.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: false }))))));
|
|
4064
|
+
}
|
|
3990
4065
|
return (React__namespace.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3991
|
-
React__namespace.createElement(
|
|
3992
|
-
React__namespace.createElement(
|
|
3993
|
-
React__namespace.createElement(MarkdownComponentsProvider, { value: components },
|
|
3994
|
-
React__namespace.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4066
|
+
React__namespace.createElement(InternalRoutes, null,
|
|
4067
|
+
React__namespace.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3995
4068
|
};
|
|
3996
4069
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3997
4070
|
return WithRouter;
|
|
@@ -4185,6 +4258,7 @@ exports.PoweredByLink = PoweredByLink;
|
|
|
4185
4258
|
exports.ReactRouterMarkdownLink = ReactRouterMarkdownLink;
|
|
4186
4259
|
exports.ResponsiveSidebarLayout = ResponsiveSidebarLayout;
|
|
4187
4260
|
exports.RouterTypeContext = RouterTypeContext;
|
|
4261
|
+
exports.ScrollToHashElement = ScrollToHashElement;
|
|
4188
4262
|
exports.SidebarLayout = SidebarLayout;
|
|
4189
4263
|
exports.Styled = Styled;
|
|
4190
4264
|
exports.TableOfContents = TableOfContents;
|
|
@@ -4196,6 +4270,8 @@ exports.findFirstNode = findFirstNode;
|
|
|
4196
4270
|
exports.isHttpOperation = isHttpOperation;
|
|
4197
4271
|
exports.isHttpService = isHttpService;
|
|
4198
4272
|
exports.isHttpWebhookOperation = isHttpWebhookOperation;
|
|
4273
|
+
exports.resolveRelativeLink = resolveRelativeLink;
|
|
4274
|
+
exports.resolveUrl = resolveUrl;
|
|
4199
4275
|
exports.slugify = slugify;
|
|
4200
4276
|
exports.useBundleRefsIntoDocument = useBundleRefsIntoDocument;
|
|
4201
4277
|
exports.useParsedData = useParsedData;
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest, __awaiter } from 'tslib';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { useContext, memo, useMemo, useState, useEffect } from 'react';
|
|
3
|
+
import React__default, { useContext, memo, useMemo, useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
4
4
|
import { convertToJsonSchema } from '@stoplight/http-spec/oas';
|
|
5
5
|
import { resolveInlineRef, hasRef, isPlainObject as isPlainObject$1, safeParse, safeStringify } from '@stoplight/json';
|
|
6
6
|
import isArray from 'lodash/isArray.js';
|
|
@@ -10,7 +10,7 @@ import { parse } from '@stoplight/yaml';
|
|
|
10
10
|
import { isArray as isArray$1, Box, useBreakpoints, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading as LinkHeading$1, NodeAnnotation, Callout, useModalState, Modal, ListBox, ListBoxItem, TabList, Tab, Tabs, TabPanels, TabPanel, Heading, useClipboard, Drawer, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
11
11
|
import isObject from 'lodash/isObject.js';
|
|
12
12
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
|
-
import { useLocation, Link as Link$1, BrowserRouter, MemoryRouter, HashRouter,
|
|
13
|
+
import { useLocation, Link as Link$1, BrowserRouter, MemoryRouter, HashRouter, useInRouterContext, Routes, Route } from 'react-router-dom';
|
|
14
14
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
15
15
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
16
16
|
import cn from 'classnames';
|
|
@@ -51,8 +51,8 @@ import keys from 'lodash/keys.js';
|
|
|
51
51
|
import sortBy from 'lodash/sortBy.js';
|
|
52
52
|
import isNil from 'lodash/isNil.js';
|
|
53
53
|
import omitBy from 'lodash/omitBy.js';
|
|
54
|
-
import { HashLink } from 'react-router-hash-link';
|
|
55
54
|
import { QueryClient, useQueryClient, QueryClientProvider } from 'react-query';
|
|
55
|
+
import { StaticRouter } from 'react-router-dom/server.js';
|
|
56
56
|
import $RefParser from '@stoplight/json-schema-ref-parser';
|
|
57
57
|
import * as PropTypes from 'prop-types';
|
|
58
58
|
import isEqual from 'lodash/isEqual.js';
|
|
@@ -1105,6 +1105,9 @@ function slugify(name) {
|
|
|
1105
1105
|
.replace(/^-/, '')
|
|
1106
1106
|
.replace(/-$/, '');
|
|
1107
1107
|
}
|
|
1108
|
+
const resolveRelativeLink = (slug) => {
|
|
1109
|
+
return slug ? slug.replace(/^\//, '') : '.';
|
|
1110
|
+
};
|
|
1108
1111
|
|
|
1109
1112
|
const isApiKeySecurityScheme = (maybeIApiKey) => isObject(maybeIApiKey) && maybeIApiKey.type === 'apiKey';
|
|
1110
1113
|
const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject(maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
|
|
@@ -3501,7 +3504,6 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3501
3504
|
const container = React.useRef(null);
|
|
3502
3505
|
const child = React.useRef(null);
|
|
3503
3506
|
const firstRender = useFirstRender();
|
|
3504
|
-
const makeSlugAbsoluteRoute = useRouterType() == 'hash';
|
|
3505
3507
|
React.useEffect(() => {
|
|
3506
3508
|
setTimeout(() => {
|
|
3507
3509
|
const scrollPosition = firstRender ? 'center' : 'nearest';
|
|
@@ -3522,7 +3524,7 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3522
3524
|
if (isDivider(item)) {
|
|
3523
3525
|
return React.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3524
3526
|
}
|
|
3525
|
-
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3527
|
+
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3526
3528
|
}))))));
|
|
3527
3529
|
});
|
|
3528
3530
|
TableOfContents.displayName = 'TableOfContents';
|
|
@@ -3530,23 +3532,23 @@ const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
|
|
|
3530
3532
|
return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3531
3533
|
});
|
|
3532
3534
|
Divider.displayName = 'Divider';
|
|
3533
|
-
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3535
|
+
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3534
3536
|
if (isExternalLink(item)) {
|
|
3535
3537
|
return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
3536
3538
|
React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, depth: depth, title: item.title, meta: React.createElement(Box, { as: Icon, icon: ['fas', 'external-link'] }) })));
|
|
3537
3539
|
}
|
|
3538
3540
|
else if (isGroup(item) || isNodeGroup(item)) {
|
|
3539
|
-
return (React.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3541
|
+
return (React.createElement(Group, { depth: depth, item: item, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3540
3542
|
}
|
|
3541
3543
|
else if (isNode(item)) {
|
|
3542
|
-
return (React.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode,
|
|
3544
|
+
return (React.createElement(Node, { depth: depth, isInResponsiveMode: isInResponsiveMode, item: item, onLinkClick: onLinkClick, meta: item.meta ? (React.createElement(Box, { color: NODE_META_COLOR[item.meta], textTransform: "uppercase", fontWeight: "medium" }, item.meta)) : (NODE_TYPE_META_ICON[item.type] && (React.createElement(Flex, { alignItems: "center" },
|
|
3543
3545
|
item.version && React.createElement(Version, { value: item.version }),
|
|
3544
3546
|
item.type !== 'model' && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_META_ICON[item.type] }))))) }));
|
|
3545
3547
|
}
|
|
3546
3548
|
return null;
|
|
3547
3549
|
});
|
|
3548
3550
|
GroupItem.displayName = 'GroupItem';
|
|
3549
|
-
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode,
|
|
3551
|
+
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3550
3552
|
const activeId = React.useContext(ActiveIdContext);
|
|
3551
3553
|
const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3552
3554
|
const hasActive = !!activeId && hasActiveItem(item.items, activeId);
|
|
@@ -3574,7 +3576,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
|
|
|
3574
3576
|
const showAsActive = hasActive && !isOpen;
|
|
3575
3577
|
let elem;
|
|
3576
3578
|
if (isNodeGroup(item)) {
|
|
3577
|
-
elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3579
|
+
elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3578
3580
|
}
|
|
3579
3581
|
else {
|
|
3580
3582
|
elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
|
|
@@ -3584,7 +3586,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
|
|
|
3584
3586
|
elem,
|
|
3585
3587
|
isOpen &&
|
|
3586
3588
|
item.items.map((groupItem, key) => {
|
|
3587
|
-
return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode
|
|
3589
|
+
return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3588
3590
|
})));
|
|
3589
3591
|
});
|
|
3590
3592
|
Group.displayName = 'Group';
|
|
@@ -3598,7 +3600,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
|
|
|
3598
3600
|
React.createElement(Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
|
|
3599
3601
|
});
|
|
3600
3602
|
Item.displayName = 'Item';
|
|
3601
|
-
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
3603
|
+
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3602
3604
|
const activeId = React.useContext(ActiveIdContext);
|
|
3603
3605
|
const isActive = activeId === item.slug || activeId === item.id;
|
|
3604
3606
|
const LinkComponent = React.useContext(LinkContext);
|
|
@@ -3614,7 +3616,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3614
3616
|
onClick(e, isActive ? undefined : true);
|
|
3615
3617
|
}
|
|
3616
3618
|
};
|
|
3617
|
-
return (React.createElement(Box, { as: LinkComponent, to:
|
|
3619
|
+
return (React.createElement(Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3618
3620
|
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3619
3621
|
});
|
|
3620
3622
|
Node.displayName = 'Node';
|
|
@@ -3638,7 +3640,8 @@ const MobileTopNav = ({ name, logo, tree, pathname, onTocClick, }) => {
|
|
|
3638
3640
|
React.createElement(Flex, { justifyContent: "end" },
|
|
3639
3641
|
React.createElement(Button, { className: "sl-mr-4 sl-mt-2", onPress: () => setIsSidebarOpen(false), appearance: "minimal", justifySelf: "end" },
|
|
3640
3642
|
React.createElement(Icon, { size: "lg", icon: faX }))),
|
|
3641
|
-
React.createElement(
|
|
3643
|
+
React.createElement(Box, { tabIndex: -1 },
|
|
3644
|
+
React.createElement(Sidebar, { name: name, logo: logo, tree: tree, pathname: pathname, onTocClick: handleTocClick, isInResponsiveMode: true })))));
|
|
3642
3645
|
};
|
|
3643
3646
|
const NavHeading = ({ heading }) => (React.createElement(Flex, { flex: 1, "data-test": "mobile-project-top-nav", style: { minWidth: 0 } },
|
|
3644
3647
|
React.createElement(Box, { fontSize: "xl", fontWeight: "semibold", whitespace: "nowrap", textOverflow: "overflow-ellipsis", overflowX: "hidden", overflowY: "hidden", w: "full", textAlign: "center" }, heading)));
|
|
@@ -3878,7 +3881,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3878
3881
|
if (isExternal) {
|
|
3879
3882
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3880
3883
|
}
|
|
3881
|
-
return (React__default.createElement(
|
|
3884
|
+
return (React__default.createElement("a", { href: href, title: title }, children));
|
|
3885
|
+
};
|
|
3886
|
+
|
|
3887
|
+
const ScrollToHashElement = ({ behavior = 'auto', initialBehavior = 'auto', inline = 'nearest', block = 'start', }) => {
|
|
3888
|
+
const [hash, setHash] = useState(window.location.hash);
|
|
3889
|
+
const [count, setCount] = useState(0);
|
|
3890
|
+
const originalListeners = useRef({});
|
|
3891
|
+
const [firstRun, setFirstRun] = useState(true);
|
|
3892
|
+
useEffect(() => setFirstRun(false), []);
|
|
3893
|
+
useEffect(() => {
|
|
3894
|
+
const handleLocationChange = () => {
|
|
3895
|
+
setHash(window.location.hash);
|
|
3896
|
+
setCount((count) => count + 1);
|
|
3897
|
+
};
|
|
3898
|
+
const onPopState = () => {
|
|
3899
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3900
|
+
};
|
|
3901
|
+
const addWindowListeners = () => {
|
|
3902
|
+
originalListeners.current.pushState = window.history.pushState;
|
|
3903
|
+
originalListeners.current.replaceState = window.history.replaceState;
|
|
3904
|
+
window.history.pushState = function (...args) {
|
|
3905
|
+
const result = originalListeners.current.pushState.apply(this, args);
|
|
3906
|
+
window.dispatchEvent(new Event('pushstate'));
|
|
3907
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3908
|
+
return result;
|
|
3909
|
+
};
|
|
3910
|
+
window.history.replaceState = function (...args) {
|
|
3911
|
+
const result = originalListeners.current.replaceState.apply(this, args);
|
|
3912
|
+
window.dispatchEvent(new Event('replacestate'));
|
|
3913
|
+
window.dispatchEvent(new Event('locationchange'));
|
|
3914
|
+
return result;
|
|
3915
|
+
};
|
|
3916
|
+
window.addEventListener('popstate', onPopState);
|
|
3917
|
+
window.addEventListener('locationchange', handleLocationChange);
|
|
3918
|
+
};
|
|
3919
|
+
const removeWindowListeners = () => {
|
|
3920
|
+
window.history.pushState = originalListeners.current.pushState;
|
|
3921
|
+
window.history.replaceState = originalListeners.current.replaceState;
|
|
3922
|
+
window.removeEventListener('popstate', onPopState);
|
|
3923
|
+
window.removeEventListener('locationchange', handleLocationChange);
|
|
3924
|
+
};
|
|
3925
|
+
addWindowListeners();
|
|
3926
|
+
return removeWindowListeners;
|
|
3927
|
+
}, []);
|
|
3928
|
+
useLayoutEffect(() => {
|
|
3929
|
+
const removeHashCharacter = (str) => {
|
|
3930
|
+
return str.slice(1);
|
|
3931
|
+
};
|
|
3932
|
+
if (hash) {
|
|
3933
|
+
const element = document.getElementById(removeHashCharacter(hash));
|
|
3934
|
+
if (element) {
|
|
3935
|
+
element.scrollIntoView({
|
|
3936
|
+
behavior: firstRun ? initialBehavior : behavior,
|
|
3937
|
+
inline: inline,
|
|
3938
|
+
block: block,
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
}, [hash, count, firstRun]);
|
|
3943
|
+
return null;
|
|
3882
3944
|
};
|
|
3883
3945
|
|
|
3884
3946
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3958,18 +4020,29 @@ const components = {
|
|
|
3958
4020
|
return React.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3959
4021
|
},
|
|
3960
4022
|
};
|
|
4023
|
+
const InternalRoutes = ({ children }) => {
|
|
4024
|
+
return (React.createElement(Routes, null,
|
|
4025
|
+
React.createElement(Route, { path: "/*", element: React.createElement(MarkdownComponentsProvider, { value: components },
|
|
4026
|
+
React.createElement(ScrollToHashElement, null),
|
|
4027
|
+
children) })));
|
|
4028
|
+
};
|
|
3961
4029
|
function withRouter(WrappedComponent) {
|
|
3962
4030
|
const WithRouter = (props) => {
|
|
3963
4031
|
var _a, _b, _c;
|
|
4032
|
+
const outerRouter = useInRouterContext();
|
|
3964
4033
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3965
4034
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3966
4035
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3967
4036
|
const { Router, routerProps } = useRouter(routerType, basePath, staticRouterPath);
|
|
4037
|
+
if (!outerRouter) {
|
|
4038
|
+
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
4039
|
+
React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
4040
|
+
React.createElement(InternalRoutes, null,
|
|
4041
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: false }))))));
|
|
4042
|
+
}
|
|
3968
4043
|
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3969
|
-
React.createElement(
|
|
3970
|
-
React.createElement(
|
|
3971
|
-
React.createElement(MarkdownComponentsProvider, { value: components },
|
|
3972
|
-
React.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4044
|
+
React.createElement(InternalRoutes, null,
|
|
4045
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3973
4046
|
};
|
|
3974
4047
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3975
4048
|
return WithRouter;
|
|
@@ -4139,4 +4212,4 @@ const createElementClass = (Component, propDescriptors) => {
|
|
|
4139
4212
|
};
|
|
4140
4213
|
};
|
|
4141
4214
|
|
|
4142
|
-
export { DeprecatedBadge, Docs, ElementsOptionsProvider, ExportButton, HttpMethodColors, InlineRefResolverProvider, LinkHeading, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, ResponsiveSidebarLayout, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useResponsiveLayout, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|
|
4215
|
+
export { DeprecatedBadge, Docs, ElementsOptionsProvider, ExportButton, HttpMethodColors, InlineRefResolverProvider, LinkHeading, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, ResponsiveSidebarLayout, RouterTypeContext, ScrollToHashElement, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, resolveRelativeLink, resolveUrl, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useResponsiveLayout, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoplight/elements-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"web-components.min.js",
|
|
@@ -46,8 +46,7 @@
|
|
|
46
46
|
"nanoid": "^3.1.32",
|
|
47
47
|
"prop-types": "^15.7.2",
|
|
48
48
|
"react-query": "^3.34.19",
|
|
49
|
-
"react-router-dom": "^
|
|
50
|
-
"react-router-hash-link": "^2.1.0",
|
|
49
|
+
"react-router-dom": "^6.28.0",
|
|
51
50
|
"tslib": "^2.1.0",
|
|
52
51
|
"urijs": "^1.19.11",
|
|
53
52
|
"util": "^0.12.4",
|
package/utils/string.d.ts
CHANGED