@stoplight/elements-core 8.5.2 → 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 +91 -19
- package/index.js +92 -17
- package/index.mjs +91 -19
- 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';
|
|
@@ -3879,7 +3881,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3879
3881
|
if (isExternal) {
|
|
3880
3882
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3881
3883
|
}
|
|
3882
|
-
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;
|
|
3883
3944
|
};
|
|
3884
3945
|
|
|
3885
3946
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3959,18 +4020,29 @@ const components = {
|
|
|
3959
4020
|
return React.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3960
4021
|
},
|
|
3961
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
|
+
};
|
|
3962
4029
|
function withRouter(WrappedComponent) {
|
|
3963
4030
|
const WithRouter = (props) => {
|
|
3964
4031
|
var _a, _b, _c;
|
|
4032
|
+
const outerRouter = useInRouterContext();
|
|
3965
4033
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3966
4034
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3967
4035
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3968
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
|
+
}
|
|
3969
4043
|
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3970
|
-
React.createElement(
|
|
3971
|
-
React.createElement(
|
|
3972
|
-
React.createElement(MarkdownComponentsProvider, { value: components },
|
|
3973
|
-
React.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4044
|
+
React.createElement(InternalRoutes, null,
|
|
4045
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3974
4046
|
};
|
|
3975
4047
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3976
4048
|
return WithRouter;
|
|
@@ -4140,4 +4212,4 @@ const createElementClass = (Component, propDescriptors) => {
|
|
|
4140
4212
|
};
|
|
4141
4213
|
};
|
|
4142
4214
|
|
|
4143
|
-
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';
|
|
@@ -3901,7 +3903,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3901
3903
|
if (isExternal) {
|
|
3902
3904
|
return (React.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3903
3905
|
}
|
|
3904
|
-
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;
|
|
3905
3966
|
};
|
|
3906
3967
|
|
|
3907
3968
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3955,7 +4016,7 @@ const RouterComponent = {
|
|
|
3955
4016
|
history: reactRouterDom.BrowserRouter,
|
|
3956
4017
|
memory: reactRouterDom.MemoryRouter,
|
|
3957
4018
|
hash: reactRouterDom.HashRouter,
|
|
3958
|
-
static:
|
|
4019
|
+
static: server_js.StaticRouter,
|
|
3959
4020
|
};
|
|
3960
4021
|
const useRouter = (router, basePath, staticRouterPath) => {
|
|
3961
4022
|
const Router = RouterComponent[router];
|
|
@@ -3981,18 +4042,29 @@ const components = {
|
|
|
3981
4042
|
return React__namespace.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3982
4043
|
},
|
|
3983
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
|
+
};
|
|
3984
4051
|
function withRouter(WrappedComponent) {
|
|
3985
4052
|
const WithRouter = (props) => {
|
|
3986
4053
|
var _a, _b, _c;
|
|
4054
|
+
const outerRouter = reactRouterDom.useInRouterContext();
|
|
3987
4055
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3988
4056
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3989
4057
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3990
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
|
+
}
|
|
3991
4065
|
return (React__namespace.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3992
|
-
React__namespace.createElement(
|
|
3993
|
-
React__namespace.createElement(
|
|
3994
|
-
React__namespace.createElement(MarkdownComponentsProvider, { value: components },
|
|
3995
|
-
React__namespace.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4066
|
+
React__namespace.createElement(InternalRoutes, null,
|
|
4067
|
+
React__namespace.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3996
4068
|
};
|
|
3997
4069
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3998
4070
|
return WithRouter;
|
|
@@ -4186,6 +4258,7 @@ exports.PoweredByLink = PoweredByLink;
|
|
|
4186
4258
|
exports.ReactRouterMarkdownLink = ReactRouterMarkdownLink;
|
|
4187
4259
|
exports.ResponsiveSidebarLayout = ResponsiveSidebarLayout;
|
|
4188
4260
|
exports.RouterTypeContext = RouterTypeContext;
|
|
4261
|
+
exports.ScrollToHashElement = ScrollToHashElement;
|
|
4189
4262
|
exports.SidebarLayout = SidebarLayout;
|
|
4190
4263
|
exports.Styled = Styled;
|
|
4191
4264
|
exports.TableOfContents = TableOfContents;
|
|
@@ -4197,6 +4270,8 @@ exports.findFirstNode = findFirstNode;
|
|
|
4197
4270
|
exports.isHttpOperation = isHttpOperation;
|
|
4198
4271
|
exports.isHttpService = isHttpService;
|
|
4199
4272
|
exports.isHttpWebhookOperation = isHttpWebhookOperation;
|
|
4273
|
+
exports.resolveRelativeLink = resolveRelativeLink;
|
|
4274
|
+
exports.resolveUrl = resolveUrl;
|
|
4200
4275
|
exports.slugify = slugify;
|
|
4201
4276
|
exports.useBundleRefsIntoDocument = useBundleRefsIntoDocument;
|
|
4202
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';
|
|
@@ -3879,7 +3881,66 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
|
3879
3881
|
if (isExternal) {
|
|
3880
3882
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
3881
3883
|
}
|
|
3882
|
-
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;
|
|
3883
3944
|
};
|
|
3884
3945
|
|
|
3885
3946
|
const NonIdealState = ({ description, icon, title }) => {
|
|
@@ -3959,18 +4020,29 @@ const components = {
|
|
|
3959
4020
|
return React.createElement(LinkHeading, Object.assign({ size: 4 }, props));
|
|
3960
4021
|
},
|
|
3961
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
|
+
};
|
|
3962
4029
|
function withRouter(WrappedComponent) {
|
|
3963
4030
|
const WithRouter = (props) => {
|
|
3964
4031
|
var _a, _b, _c;
|
|
4032
|
+
const outerRouter = useInRouterContext();
|
|
3965
4033
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
3966
4034
|
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
3967
4035
|
const routerType = (_c = props.router) !== null && _c !== void 0 ? _c : 'history';
|
|
3968
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
|
+
}
|
|
3969
4043
|
return (React.createElement(RouterTypeContext.Provider, { value: routerType },
|
|
3970
|
-
React.createElement(
|
|
3971
|
-
React.createElement(
|
|
3972
|
-
React.createElement(MarkdownComponentsProvider, { value: components },
|
|
3973
|
-
React.createElement(WrappedComponent, Object.assign({}, props)))))));
|
|
4044
|
+
React.createElement(InternalRoutes, null,
|
|
4045
|
+
React.createElement(WrappedComponent, Object.assign({}, props, { outerRouter: true })))));
|
|
3974
4046
|
};
|
|
3975
4047
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
|
3976
4048
|
return WithRouter;
|
|
@@ -4140,4 +4212,4 @@ const createElementClass = (Component, propDescriptors) => {
|
|
|
4140
4212
|
};
|
|
4141
4213
|
};
|
|
4142
4214
|
|
|
4143
|
-
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