@redocly/theme 0.55.0-next.0 → 0.55.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ const Link_1 = require("../../components/Link/Link");
12
12
  const Image_1 = require("../../components/Image/Image");
13
13
  const utils_1 = require("../../core/utils");
14
14
  function FooterItem({ item, iconsOnly, className }) {
15
+ var _a, _b;
15
16
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
16
17
  const telemetry = useTelemetry();
17
18
  const { translate } = useTranslate();
@@ -22,7 +23,9 @@ function FooterItem({ item, iconsOnly, className }) {
22
23
  const iconWithoutLabel = Boolean(item.label === item.link && hasIcon);
23
24
  return (react_1.default.createElement(FooterItemWrapper, { className: className, "data-component-name": "Footer/FooterItem", iconsOnly: iconsOnly, item: item }, item.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label))) : (react_1.default.createElement(FooterLink, { to: item.link, external: item.external, target: item.target, "data-testid": item.label, onClick: () => telemetry.send({ type: 'footer_item.clicked' }), "data-translation-key": item.labelTranslationKey },
24
25
  hasIcon ? (react_1.default.createElement(FooterLinkIcon, { iconsOnly: iconsOnly },
25
- react_1.default.createElement(Image_1.Image, { src: item.icon, srcSet: item.srcSet }))) : null,
26
+ react_1.default.createElement(Image_1.Image, { src: item.icon, srcSet: item.srcSet, alt: item.label && item.label !== item.link
27
+ ? `${item.label} icon`
28
+ : `${(_b = (_a = (item.icon || item.srcSet)) === null || _a === void 0 ? void 0 : _a.split('/').pop()) === null || _b === void 0 ? void 0 : _b.split('.')[0]} icon` }))) : null,
26
29
  !iconWithoutLabel ? translate(item.labelTranslationKey, item.label) : null,
27
30
  item.external ? react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "10px" }) : null))));
28
31
  }
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { CodeBlockControlsProps } from '../../components/CodeBlock/CodeBlockControls';
3
+ export type PanelType = 'request' | 'responses' | 'request-samples' | 'response-samples';
3
4
  export type JsonProps = {
4
5
  title?: CodeBlockControlsProps['title'];
5
6
  data: any;
@@ -8,6 +9,7 @@ export type JsonProps = {
8
9
  startLineNumber?: number;
9
10
  hideHeader?: boolean;
10
11
  onCopyClick?: () => void;
12
+ onPanelToggle?: (isExpanded: boolean, panelType?: PanelType) => void;
11
13
  };
12
14
  export declare const JsonViewer: React.NamedExoticComponent<JsonProps>;
13
15
  export declare const JsonViewerWrap: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -31,17 +31,19 @@ const react_1 = __importStar(require("react"));
31
31
  const styled_components_1 = __importDefault(require("styled-components"));
32
32
  const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
33
33
  const helpers_1 = require("./helpers");
34
- function JsonComponent({ data, expandLevel = 1, className, onCopyClick, title, hideHeader, }) {
34
+ function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelToggle, title, hideHeader, }) {
35
35
  const showFoldingButtons = data && Object.values(data).some((value) => typeof value === 'object' && value !== null);
36
36
  const [expandAllSignal, setExpandAllSignal] = react_1.default.useState(undefined);
37
37
  const expandAll = () => {
38
38
  setExpandAllSignal(true);
39
+ onPanelToggle === null || onPanelToggle === void 0 ? void 0 : onPanelToggle(true);
39
40
  setTimeout(() => {
40
41
  setExpandAllSignal(undefined);
41
42
  });
42
43
  };
43
44
  const collapseAll = () => {
44
45
  setExpandAllSignal(false);
46
+ onPanelToggle === null || onPanelToggle === void 0 ? void 0 : onPanelToggle(false);
45
47
  setTimeout(() => {
46
48
  setExpandAllSignal(undefined);
47
49
  });
@@ -38,7 +38,8 @@ function SearchTrigger({ onClick, className }) {
38
38
  const themeSettings = (0, hooks_1.useThemeConfig)();
39
39
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
40
40
  const { translate } = useTranslate();
41
- const keyShortcuts = (_b = (_a = themeSettings === null || themeSettings === void 0 ? void 0 : themeSettings.search) === null || _a === void 0 ? void 0 : _a.shortcuts) !== null && _b !== void 0 ? _b : ['/'];
41
+ const defaultKeyShortcut = '⌘+K,CTRL+K';
42
+ const keyShortcuts = (_b = (_a = themeSettings === null || themeSettings === void 0 ? void 0 : themeSettings.search) === null || _a === void 0 ? void 0 : _a.shortcuts) !== null && _b !== void 0 ? _b : [defaultKeyShortcut];
42
43
  let mainShortcutKey = null;
43
44
  if (keyShortcuts) {
44
45
  if (Array.isArray(keyShortcuts)) {
@@ -49,12 +50,13 @@ function SearchTrigger({ onClick, className }) {
49
50
  }
50
51
  }
51
52
  mainShortcutKey = mainShortcutKey === null || mainShortcutKey === void 0 ? void 0 : mainShortcutKey.toUpperCase();
53
+ const isMac = (0, utils_1.getUserAgent)().includes('Mac');
52
54
  return (React.createElement(SearchTriggerWrapper, { onClick: onClick, className: className, "data-component-name": "Search/SearchTrigger" },
53
55
  React.createElement(SearchTriggerButton, { "data-testid": "search-trigger-button", variant: "text", size: "medium", icon: React.createElement(SearchIcon_1.SearchIcon, null) }),
54
56
  React.createElement(SearchTriggerInput, { "data-testid": "search-trigger-input", "data-translation-key": "search.navbar.label" },
55
57
  React.createElement(SearchIcon_1.SearchIcon, null),
56
58
  translate('search.navbar.label', 'Search'),
57
- mainShortcutKey && React.createElement("span", null, mainShortcutKey))));
59
+ mainShortcutKey === defaultKeyShortcut ? (React.createElement("span", null, isMac ? '⌘K' : 'Ctrl+K')) : (React.createElement("span", null, mainShortcutKey)))));
58
60
  }
59
61
  const SearchTriggerWrapper = styled_components_1.default.div `
60
62
  color: var(--search-trigger-color);
@@ -36,3 +36,5 @@ export * from '../../core/hooks/code-walkthrough/use-renderable-files';
36
36
  export * from '../../core/hooks/use-element-size';
37
37
  export * from '../../core/hooks/use-time-ago';
38
38
  export * from '../../core/hooks/use-input-key-commands';
39
+ export * from '../../core/hooks/use-page-active-version';
40
+ export * from '../../core/hooks/use-page-versions';
@@ -52,4 +52,6 @@ __exportStar(require("../../core/hooks/code-walkthrough/use-renderable-files"),
52
52
  __exportStar(require("../../core/hooks/use-element-size"), exports);
53
53
  __exportStar(require("../../core/hooks/use-time-ago"), exports);
54
54
  __exportStar(require("../../core/hooks/use-input-key-commands"), exports);
55
+ __exportStar(require("../../core/hooks/use-page-active-version"), exports);
56
+ __exportStar(require("../../core/hooks/use-page-versions"), exports);
55
57
  //# sourceMappingURL=index.js.map
@@ -15,7 +15,7 @@ function useSearchDialog() {
15
15
  const location = (0, react_router_dom_1.useLocation)();
16
16
  const { useTelemetry } = (0, hooks_1.useThemeHooks)();
17
17
  const telemetry = useTelemetry();
18
- const keyShortcuts = (_b = (_a = themeSettings === null || themeSettings === void 0 ? void 0 : themeSettings.search) === null || _a === void 0 ? void 0 : _a.shortcuts) !== null && _b !== void 0 ? _b : ['/'];
18
+ const keyShortcuts = (_b = (_a = themeSettings === null || themeSettings === void 0 ? void 0 : themeSettings.search) === null || _a === void 0 ? void 0 : _a.shortcuts) !== null && _b !== void 0 ? _b : ['⌘+K,CTRL+K'];
19
19
  const hotKeys = keyShortcuts === null || keyShortcuts === void 0 ? void 0 : keyShortcuts.join(',');
20
20
  (0, react_1.useEffect)(() => {
21
21
  if (hotKeys) {
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useInputKeyCommands = useInputKeyCommands;
4
4
  const react_1 = require("react");
5
+ const utils_1 = require("../../core/utils");
5
6
  function useInputKeyCommands(actionHandlers) {
6
7
  // MacOS uses Command key instead of Ctrl
7
- const ctrlKey = (0, react_1.useMemo)(() => (navigator.userAgent.includes('Mac') ? 'metaKey' : 'ctrlKey'), []);
8
+ const ctrlKey = (0, react_1.useMemo)(() => ((0, utils_1.getUserAgent)().includes('Mac') ? 'metaKey' : 'ctrlKey'), []);
8
9
  const isSelectAll = (0, react_1.useCallback)((event) => {
9
10
  return event.key === 'a' && event[ctrlKey];
10
11
  }, [ctrlKey]);
@@ -0,0 +1 @@
1
+ export declare function usePageActiveVersion(): string | undefined;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePageActiveVersion = usePageActiveVersion;
4
+ const hooks_1 = require("../../core/hooks");
5
+ function usePageActiveVersion() {
6
+ const { usePageVersions } = (0, hooks_1.useThemeHooks)();
7
+ const { versions } = usePageVersions();
8
+ const activeVersion = versions.find((version) => version.active);
9
+ return activeVersion === null || activeVersion === void 0 ? void 0 : activeVersion.version;
10
+ }
11
+ //# sourceMappingURL=use-page-active-version.js.map
@@ -0,0 +1,7 @@
1
+ export type PageVersion = {
2
+ active: boolean;
3
+ default: boolean;
4
+ label: string;
5
+ version: string;
6
+ };
7
+ export declare function usePageVersions(): PageVersion[];
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePageVersions = usePageVersions;
4
+ const hooks_1 = require("../../core/hooks");
5
+ function usePageVersions() {
6
+ const { usePageVersions } = (0, hooks_1.useThemeHooks)();
7
+ const pageVersions = usePageVersions();
8
+ return pageVersions.versions.map((version) => ({
9
+ active: version.active,
10
+ default: version.default,
11
+ label: version.label,
12
+ version: version.version,
13
+ }));
14
+ }
15
+ //# sourceMappingURL=use-page-versions.js.map
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Returns user agent. Handles SSR and browser.
3
+ */
4
+ export declare function getUserAgent(): any;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUserAgent = getUserAgent;
4
+ /**
5
+ * Returns user agent. Handles SSR and browser.
6
+ */
7
+ function getUserAgent() {
8
+ const ssrUserAgent = globalThis['SSR_USER_AGENT'];
9
+ if (ssrUserAgent) {
10
+ return ssrUserAgent;
11
+ }
12
+ const browserUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : '';
13
+ return browserUserAgent;
14
+ }
15
+ //# sourceMappingURL=get-user-agent.js.map
@@ -31,3 +31,4 @@ export * from '../../core/utils/get-file-icon';
31
31
  export * from '../../core/utils/match-code-walkthrough-conditions';
32
32
  export * from '../../core/utils/replace-inputs-with-value';
33
33
  export * from '../../core/utils/find-closest-common-directory';
34
+ export * from '../../core/utils/get-user-agent';
@@ -47,4 +47,5 @@ __exportStar(require("../../core/utils/get-file-icon"), exports);
47
47
  __exportStar(require("../../core/utils/match-code-walkthrough-conditions"), exports);
48
48
  __exportStar(require("../../core/utils/replace-inputs-with-value"), exports);
49
49
  __exportStar(require("../../core/utils/find-closest-common-directory"), exports);
50
+ __exportStar(require("../../core/utils/get-user-agent"), exports);
50
51
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.55.0-next.0",
3
+ "version": "0.55.0-next.2",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -88,7 +88,7 @@
88
88
  "nprogress": "0.2.0",
89
89
  "react-calendar": "5.1.0",
90
90
  "react-date-picker": "11.0.0",
91
- "@redocly/config": "0.26.0",
91
+ "@redocly/config": "0.26.1",
92
92
  "@redocly/realm-asyncapi-sdk": "0.1.0-next.0"
93
93
  },
94
94
  "scripts": {
@@ -48,7 +48,15 @@ export function FooterItem({ item, iconsOnly, className }: FooterItemProps): JSX
48
48
  >
49
49
  {hasIcon ? (
50
50
  <FooterLinkIcon iconsOnly={iconsOnly}>
51
- <Image src={item.icon} srcSet={item.srcSet} />
51
+ <Image
52
+ src={item.icon}
53
+ srcSet={item.srcSet}
54
+ alt={
55
+ item.label && item.label !== item.link
56
+ ? `${item.label} icon`
57
+ : `${(item.icon || item.srcSet)?.split('/').pop()?.split('.')[0]} icon`
58
+ }
59
+ />
52
60
  </FooterLinkIcon>
53
61
  ) : null}
54
62
  {!iconWithoutLabel ? translate(item.labelTranslationKey, item.label) : null}
@@ -8,6 +8,8 @@ import { CodeBlock } from '@redocly/theme/components/CodeBlock/CodeBlock';
8
8
 
9
9
  import { JsonValue } from './helpers';
10
10
 
11
+ export type PanelType = 'request' | 'responses' | 'request-samples' | 'response-samples';
12
+
11
13
  export type JsonProps = {
12
14
  title?: CodeBlockControlsProps['title'];
13
15
  data: any;
@@ -16,6 +18,7 @@ export type JsonProps = {
16
18
  startLineNumber?: number;
17
19
  hideHeader?: boolean;
18
20
  onCopyClick?: () => void;
21
+ onPanelToggle?: (isExpanded: boolean, panelType?: PanelType) => void;
19
22
  };
20
23
 
21
24
  function JsonComponent({
@@ -23,6 +26,7 @@ function JsonComponent({
23
26
  expandLevel = 1,
24
27
  className,
25
28
  onCopyClick,
29
+ onPanelToggle,
26
30
  title,
27
31
  hideHeader,
28
32
  }: JsonProps): JSX.Element {
@@ -33,6 +37,7 @@ function JsonComponent({
33
37
 
34
38
  const expandAll = () => {
35
39
  setExpandAllSignal(true);
40
+ onPanelToggle?.(true);
36
41
  setTimeout(() => {
37
42
  setExpandAllSignal(undefined);
38
43
  });
@@ -40,6 +45,7 @@ function JsonComponent({
40
45
 
41
46
  const collapseAll = () => {
42
47
  setExpandAllSignal(false);
48
+ onPanelToggle?.(false);
43
49
  setTimeout(() => {
44
50
  setExpandAllSignal(undefined);
45
51
  });
@@ -6,7 +6,7 @@ import type { JSX } from 'react';
6
6
  import { useThemeConfig, useThemeHooks } from '@redocly/theme/core/hooks';
7
7
  import { Button } from '@redocly/theme/components/Button/Button';
8
8
  import { SearchIcon } from '@redocly/theme/icons/SearchIcon/SearchIcon';
9
- import { breakpoints } from '@redocly/theme/core/utils';
9
+ import { breakpoints, getUserAgent } from '@redocly/theme/core/utils';
10
10
 
11
11
  export type SearchTriggerProps = {
12
12
  onClick: () => void;
@@ -18,7 +18,8 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
18
18
  const { useTranslate } = useThemeHooks();
19
19
  const { translate } = useTranslate();
20
20
 
21
- const keyShortcuts = themeSettings?.search?.shortcuts ?? ['/'];
21
+ const defaultKeyShortcut = '⌘+K,CTRL+K';
22
+ const keyShortcuts = themeSettings?.search?.shortcuts ?? [defaultKeyShortcut];
22
23
  let mainShortcutKey: string | null | undefined = null;
23
24
 
24
25
  if (keyShortcuts) {
@@ -30,6 +31,7 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
30
31
  }
31
32
 
32
33
  mainShortcutKey = mainShortcutKey?.toUpperCase();
34
+ const isMac = getUserAgent().includes('Mac');
33
35
 
34
36
  return (
35
37
  <SearchTriggerWrapper
@@ -49,7 +51,11 @@ export function SearchTrigger({ onClick, className }: SearchTriggerProps): JSX.E
49
51
  >
50
52
  <SearchIcon />
51
53
  {translate('search.navbar.label', 'Search')}
52
- {mainShortcutKey && <span>{mainShortcutKey}</span>}
54
+ {mainShortcutKey === defaultKeyShortcut ? (
55
+ <span>{isMac ? '⌘K' : 'Ctrl+K'}</span>
56
+ ) : (
57
+ <span>{mainShortcutKey}</span>
58
+ )}
53
59
  </SearchTriggerInput>
54
60
  </SearchTriggerWrapper>
55
61
  );
@@ -36,3 +36,5 @@ export * from '@redocly/theme/core/hooks/code-walkthrough/use-renderable-files';
36
36
  export * from '@redocly/theme/core/hooks/use-element-size';
37
37
  export * from '@redocly/theme/core/hooks/use-time-ago';
38
38
  export * from '@redocly/theme/core/hooks/use-input-key-commands';
39
+ export * from '@redocly/theme/core/hooks/use-page-active-version';
40
+ export * from '@redocly/theme/core/hooks/use-page-versions';
@@ -10,7 +10,7 @@ export function useSearchDialog() {
10
10
  const location = useLocation();
11
11
  const { useTelemetry } = useThemeHooks();
12
12
  const telemetry = useTelemetry();
13
- const keyShortcuts = themeSettings?.search?.shortcuts ?? ['/'];
13
+ const keyShortcuts = themeSettings?.search?.shortcuts ?? ['⌘+K,CTRL+K'];
14
14
  const hotKeys = keyShortcuts?.join(',');
15
15
 
16
16
  useEffect(() => {
@@ -1,5 +1,7 @@
1
1
  import { useCallback, useMemo } from 'react';
2
2
 
3
+ import { getUserAgent } from '@redocly/theme/core/utils';
4
+
3
5
  type Action = 'selectAll' | 'escape' | 'clear' | 'enter' | 'paste';
4
6
  type ActionHandlers = {
5
7
  [key in `on${Capitalize<Action>}`]?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
@@ -11,7 +13,7 @@ type KeyboardCommand = {
11
13
 
12
14
  export function useInputKeyCommands(actionHandlers?: ActionHandlers) {
13
15
  // MacOS uses Command key instead of Ctrl
14
- const ctrlKey = useMemo(() => (navigator.userAgent.includes('Mac') ? 'metaKey' : 'ctrlKey'), []);
16
+ const ctrlKey = useMemo(() => (getUserAgent().includes('Mac') ? 'metaKey' : 'ctrlKey'), []);
15
17
 
16
18
  const isSelectAll = useCallback(
17
19
  (event: React.KeyboardEvent<HTMLInputElement>) => {
@@ -0,0 +1,9 @@
1
+ import { useThemeHooks } from '@redocly/theme/core/hooks';
2
+
3
+ export function usePageActiveVersion(): string | undefined {
4
+ const { usePageVersions } = useThemeHooks();
5
+ const { versions } = usePageVersions();
6
+ const activeVersion = versions.find((version) => version.active);
7
+
8
+ return activeVersion?.version;
9
+ }
@@ -0,0 +1,20 @@
1
+ import { useThemeHooks } from '@redocly/theme/core/hooks';
2
+
3
+ export type PageVersion = {
4
+ active: boolean;
5
+ default: boolean;
6
+ label: string;
7
+ version: string;
8
+ };
9
+
10
+ export function usePageVersions(): PageVersion[] {
11
+ const { usePageVersions } = useThemeHooks();
12
+ const pageVersions = usePageVersions();
13
+
14
+ return pageVersions.versions.map((version) => ({
15
+ active: version.active,
16
+ default: version.default,
17
+ label: version.label,
18
+ version: version.version,
19
+ }));
20
+ }
@@ -214,7 +214,7 @@ export type TranslationKey =
214
214
  | 'openapi.showExample'
215
215
  | 'openapi.expandAll'
216
216
  | 'openapi.collapseAll'
217
- | 'openapi.viewDetails'
217
+ | 'openapi.viewSecurityDetails'
218
218
  | 'openapi.noResponseExample'
219
219
  | 'openapi.noResponseContent'
220
220
  | 'openapi.noRequestPayload'
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Returns user agent. Handles SSR and browser.
3
+ */
4
+ export function getUserAgent() {
5
+ const ssrUserAgent = (globalThis as any)['SSR_USER_AGENT'];
6
+
7
+ if (ssrUserAgent) {
8
+ return ssrUserAgent;
9
+ }
10
+ const browserUserAgent = typeof navigator !== 'undefined' ? navigator.userAgent : '';
11
+
12
+ return browserUserAgent;
13
+ }
@@ -31,3 +31,4 @@ export * from '@redocly/theme/core/utils/get-file-icon';
31
31
  export * from '@redocly/theme/core/utils/match-code-walkthrough-conditions';
32
32
  export * from '@redocly/theme/core/utils/replace-inputs-with-value';
33
33
  export * from '@redocly/theme/core/utils/find-closest-common-directory';
34
+ export * from '@redocly/theme/core/utils/get-user-agent';
package/src/settings.yaml CHANGED
@@ -1,6 +1,7 @@
1
1
  search:
2
2
  hide: false
3
3
  placement: navbar
4
+ shortcuts: ['⌘+K,ctrl+K']
4
5
  toc:
5
6
  hide: false
6
7
  header: