@redocly/theme 0.46.1 → 0.46.3

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.
@@ -156,6 +156,13 @@ const SearchOverlay = styled_components_1.default.div `
156
156
  height: 100vh;
157
157
  background: var(--bg-color-modal-overlay);
158
158
  z-index: var(--z-index-overlay);
159
+
160
+ @media screen and (max-width: ${utils_1.breakpoints.small}) {
161
+ align-items: start;
162
+ position: fixed;
163
+ overflow: hidden;
164
+ overscroll-behavior: none;
165
+ }
159
166
  `;
160
167
  const SearchDialogWrapper = styled_components_1.default.div `
161
168
  display: flex;
@@ -168,9 +175,10 @@ const SearchDialogWrapper = styled_components_1.default.div `
168
175
  border-radius: 0;
169
176
 
170
177
  @media screen and (max-width: ${utils_1.breakpoints.small}) {
171
- /* Ignore resize on mobile */
178
+ min-height: -webkit-fill-available !important;
179
+ min-height: 100dvh !important;
180
+ height: auto !important;
172
181
  width: 100vw !important;
173
- height: 100vh !important;
174
182
  }
175
183
 
176
184
  @media screen and (min-width: ${utils_1.breakpoints.small}) {
@@ -196,6 +204,10 @@ const SearchDialogBody = styled_components_1.default.div `
196
204
  flex-direction: row;
197
205
  flex-grow: 1;
198
206
  overflow: hidden;
207
+
208
+ @media screen and (max-width: ${utils_1.breakpoints.small}) {
209
+ min-height: 0;
210
+ }
199
211
  `;
200
212
  const SearchDialogBodyMainView = styled_components_1.default.div `
201
213
  flex: 2;
@@ -8,7 +8,6 @@ const react_1 = __importDefault(require("react"));
8
8
  const styled_components_1 = __importDefault(require("styled-components"));
9
9
  const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
10
10
  const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
11
- const GridIcon_1 = require("../../icons/GridIcon/GridIcon");
12
11
  const hooks_1 = require("../../core/hooks");
13
12
  const LoginButton_1 = require("../../components/UserMenu/LoginButton");
14
13
  const UserAvatar_1 = require("../../components/UserMenu/UserAvatar");
@@ -19,7 +18,7 @@ const utils_1 = require("../../core/utils");
19
18
  function UserMenu({ className }) {
20
19
  const { userMenu } = (0, hooks_1.useThemeConfig)();
21
20
  const { useTranslate, useUserMenu } = (0, hooks_1.useThemeHooks)();
22
- const { userData, hasDeveloperOnboarding, loginUrl } = useUserMenu();
21
+ const { userData, loginUrl } = useUserMenu();
23
22
  const { translate } = useTranslate();
24
23
  if (!(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated)) {
25
24
  if (loginUrl && !(userMenu === null || userMenu === void 0 ? void 0 : userMenu.hideLoginButton)) {
@@ -30,17 +29,11 @@ function UserMenu({ className }) {
30
29
  return null;
31
30
  }
32
31
  }
33
- const devOnboardingMenuItem = hasDeveloperOnboarding
34
- ? [
35
- react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: "my-apps", to: "/apps", "data-translation-key": "userMenu.devOnboardingLabel", prefix: react_1.default.createElement(GridIcon_1.GridIcon, null) }, translate('userMenu.devOnboardingLabel')),
36
- ]
37
- : [];
38
32
  const menuItems = (userMenu === null || userMenu === void 0 ? void 0 : userMenu['menu']) || [];
39
- const customItems = menuItems.map((item) => (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: item.label, external: item.external, to: item.link || '' }, item.label)));
33
+ const customItems = menuItems.map((item) => (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: item.label, external: item.external, to: item.link || '' }, item.labelTranslationKey ? translate(item.labelTranslationKey) : item.label)));
40
34
  const items = [
41
35
  react_1.default.createElement(UserInfoMenuItem_1.UserInfoMenuItem, { name: userData.name, picture: userData.picture, email: userData.email, key: "userinfo" }),
42
36
  react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { separatorLine: true, separator: true, key: "separator" }),
43
- ...devOnboardingMenuItem,
44
37
  ...customItems,
45
38
  react_1.default.createElement(LogoutMenuItem_1.LogoutMenuItem, { key: "logout" }),
46
39
  ];
@@ -62,4 +62,5 @@ export declare const useThemeHooks: jest.Mock<{
62
62
  useSubmitFeedback: jest.Mock<{
63
63
  submitFeedback: jest.Mock<any, any, any>;
64
64
  }, [], any>;
65
+ useLoadAndNavigate: jest.Mock<any, any, any>;
65
66
  }, [], any>;
@@ -85,5 +85,6 @@ exports.useThemeHooks = jest.fn(() => ({
85
85
  useSubmitFeedback: jest.fn(() => ({
86
86
  submitFeedback: jest.fn(),
87
87
  })),
88
+ useLoadAndNavigate: jest.fn(),
88
89
  }));
89
90
  //# sourceMappingURL=use-theme-hooks.js.map
@@ -58,7 +58,7 @@ function useNestedMenu({ item, labelRef, nestedMenuRef }) {
58
58
  }
59
59
  const [firstChild] = item.items;
60
60
  if (!isExpanded && item.selectFirstItemOnExpand && firstChild.link) {
61
- yield (0, utils_1.loadAndNavigate)(navigate, firstChild.link);
61
+ yield (0, utils_1.loadAndNavigate)({ navigate, to: firstChild.link });
62
62
  }
63
63
  setIsExpanded(!isExpanded);
64
64
  }), [item, isExpanded, navigate, location.pathname, setIsExpanded]);
@@ -1,17 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useLanguagePicker = useLanguagePicker;
4
+ const react_router_dom_1 = require("react-router-dom");
4
5
  const hooks_1 = require("../../core/hooks");
5
6
  const utils_1 = require("../../core/utils");
6
7
  function useLanguagePicker() {
7
- const { useL10nConfig, usePreloadHistory } = (0, hooks_1.useThemeHooks)();
8
- const history = usePreloadHistory();
8
+ const { useL10nConfig, useLoadAndNavigate } = (0, hooks_1.useThemeHooks)();
9
+ const navigate = (0, react_router_dom_1.useNavigate)();
10
+ const loadAndNavigate = useLoadAndNavigate();
9
11
  const { currentLocale, locales, defaultLocale } = useL10nConfig();
10
12
  const locale = locales.find((l) => l.code === currentLocale);
11
13
  function setLocale(value) {
12
14
  const newLangPathname = (0, utils_1.withPathPrefix)((0, utils_1.getPathnameForLocale)(location.pathname, defaultLocale, value, locales));
13
15
  const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
14
- history.push(newUrlWithLanguage);
16
+ loadAndNavigate({ navigate, to: newUrlWithLanguage });
15
17
  }
16
18
  return {
17
19
  currentLocale: locale,
@@ -1,18 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useProductPicker = useProductPicker;
4
+ const react_router_dom_1 = require("react-router-dom");
4
5
  const hooks_1 = require("../../core/hooks");
5
6
  function useProductPicker() {
6
- const { useCurrentProduct, useProducts, usePreloadHistory, useTelemetry } = (0, hooks_1.useThemeHooks)();
7
+ const { useCurrentProduct, useProducts, useTelemetry, useLoadAndNavigate } = (0, hooks_1.useThemeHooks)();
7
8
  const currentProduct = useCurrentProduct();
8
9
  const products = useProducts();
9
10
  const telemetry = useTelemetry();
10
- const history = usePreloadHistory();
11
+ const navigate = (0, react_router_dom_1.useNavigate)();
12
+ const loadAndNavigate = useLoadAndNavigate();
11
13
  function setProduct(product) {
12
14
  if (!product)
13
15
  return;
14
16
  telemetry.send('product_picked', { product: product.slug });
15
- history.push(product.link);
17
+ loadAndNavigate({ navigate, to: product.link });
16
18
  }
17
19
  return {
18
20
  currentProduct,
@@ -1,6 +1,6 @@
1
1
  import type { PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
2
2
  import type { Callback, TFunction as TFunc } from 'i18next';
3
- import type { To, Location } from 'react-router-dom';
3
+ import type { To, Location, NavigateFunction } from 'react-router-dom';
4
4
  import type { CatalogConfig, ProductUiConfig } from '../../config';
5
5
  import type { UserMenuData, FilteredCatalog, ItemState, SearchItemData, SubmitFeedbackParams, TFunction, BreadcrumbItem, DrilldownMenuItemDetails, SearchFacet, SearchFilterItem, SearchFacetQuery } from '../../core/types';
6
6
  export type ThemeHooks = {
@@ -105,6 +105,10 @@ export type ThemeHooks = {
105
105
  highlight?: string;
106
106
  }) => string;
107
107
  };
108
+ useLoadAndNavigate: () => (options: {
109
+ navigate: NavigateFunction;
110
+ to: string;
111
+ }) => Promise<void>;
108
112
  };
109
113
  export type L10nConfig = {
110
114
  currentLocale: string;
@@ -1,3 +1,8 @@
1
1
  import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
2
2
  export type HistoryOrigin = 'pm' | 'browser';
3
- export declare function loadAndNavigate(navigate: NavigateFunction, to: string, origin?: HistoryOrigin, options?: NavigateOptions): Promise<void>;
3
+ export declare function loadAndNavigate({ navigate, to, origin, options, }: {
4
+ navigate: NavigateFunction;
5
+ to: string;
6
+ origin?: HistoryOrigin;
7
+ options?: NavigateOptions;
8
+ }): Promise<void>;
@@ -12,9 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.loadAndNavigate = loadAndNavigate;
13
13
  const utils_1 = require("../../core/utils");
14
14
  let lastNavigatedPath;
15
- function loadAndNavigate(navigate_1, to_1) {
16
- return __awaiter(this, arguments, void 0, function* (navigate, to, origin = 'browser', options) {
17
- var _a;
15
+ // this is copy from portal/src/client/app/utils/loadAndNavigate.ts, for case when we need to run Redoc without Realm
16
+ function loadAndNavigate(_a) {
17
+ return __awaiter(this, arguments, void 0, function* ({ navigate, to, origin = 'browser', options, }) {
18
+ var _b;
18
19
  lastNavigatedPath = to;
19
20
  const { pathname, hash, search } = new URL(to, window.location.origin + window.location.pathname);
20
21
  // use window-shared loader instead of importing to prevent circular import issue
@@ -23,7 +24,7 @@ function loadAndNavigate(navigate_1, to_1) {
23
24
  // @ts-ignore
24
25
  if (result === null || result === void 0 ? void 0 : result.redirectTo) {
25
26
  // @ts-ignore
26
- return loadAndNavigate(navigate, result.redirectTo, origin, options);
27
+ return loadAndNavigate({ navigate, to: result.redirectTo, origin, options });
27
28
  }
28
29
  if (result && lastNavigatedPath === to) {
29
30
  if (pathname !== window.location.pathname || search !== window.location.search) {
@@ -31,7 +32,7 @@ function loadAndNavigate(navigate_1, to_1) {
31
32
  navigate({ pathname, search, hash }, Object.assign(Object.assign({}, options), { state: { origin }, unstable_flushSync: true }));
32
33
  }
33
34
  // @ts-ignore
34
- if ((_a = result.props) === null || _a === void 0 ? void 0 : _a.disableAutoScroll)
35
+ if ((_b = result.props) === null || _b === void 0 ? void 0 : _b.disableAutoScroll)
35
36
  return;
36
37
  if (hash) {
37
38
  const el = document.getElementById(hash.slice(1));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.46.1",
3
+ "version": "0.46.3",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -79,7 +79,7 @@
79
79
  "timeago.js": "4.0.2",
80
80
  "i18next": "22.4.15",
81
81
  "nprogress": "0.2.0",
82
- "@redocly/config": "0.19.0"
82
+ "@redocly/config": "0.19.1"
83
83
  },
84
84
  "scripts": {
85
85
  "watch": "tsc -p tsconfig.build.json && (concurrently \"tsc -w -p tsconfig.build.json\" \"tsc-alias -w -p tsconfig.build.json\")",
@@ -280,6 +280,13 @@ const SearchOverlay = styled.div`
280
280
  height: 100vh;
281
281
  background: var(--bg-color-modal-overlay);
282
282
  z-index: var(--z-index-overlay);
283
+
284
+ @media screen and (max-width: ${breakpoints.small}) {
285
+ align-items: start;
286
+ position: fixed;
287
+ overflow: hidden;
288
+ overscroll-behavior: none;
289
+ }
283
290
  `;
284
291
 
285
292
  const SearchDialogWrapper = styled.div`
@@ -293,9 +300,10 @@ const SearchDialogWrapper = styled.div`
293
300
  border-radius: 0;
294
301
 
295
302
  @media screen and (max-width: ${breakpoints.small}) {
296
- /* Ignore resize on mobile */
303
+ min-height: -webkit-fill-available !important;
304
+ min-height: 100dvh !important;
305
+ height: auto !important;
297
306
  width: 100vw !important;
298
- height: 100vh !important;
299
307
  }
300
308
 
301
309
  @media screen and (min-width: ${breakpoints.small}) {
@@ -323,6 +331,10 @@ const SearchDialogBody = styled.div`
323
331
  flex-direction: row;
324
332
  flex-grow: 1;
325
333
  overflow: hidden;
334
+
335
+ @media screen and (max-width: ${breakpoints.small}) {
336
+ min-height: 0;
337
+ }
326
338
  `;
327
339
 
328
340
  const SearchDialogBodyMainView = styled.div`
@@ -5,7 +5,6 @@ import type { ResolvedNavLinkItem } from '@redocly/config';
5
5
 
6
6
  import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
7
7
  import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
8
- import { GridIcon } from '@redocly/theme/icons/GridIcon/GridIcon';
9
8
  import { useThemeHooks, useThemeConfig } from '@redocly/theme/core/hooks';
10
9
  import { LoginButton } from '@redocly/theme/components/UserMenu/LoginButton';
11
10
  import { UserAvatar } from '@redocly/theme/components/UserMenu/UserAvatar';
@@ -25,7 +24,7 @@ export function UserMenu({ className }: UserMenuProps) {
25
24
  };
26
25
  }>();
27
26
  const { useTranslate, useUserMenu } = useThemeHooks();
28
- const { userData, hasDeveloperOnboarding, loginUrl } = useUserMenu();
27
+ const { userData, loginUrl } = useUserMenu();
29
28
  const { translate } = useTranslate();
30
29
 
31
30
  if (!userData?.isAuthenticated) {
@@ -40,24 +39,11 @@ export function UserMenu({ className }: UserMenuProps) {
40
39
  }
41
40
  }
42
41
 
43
- const devOnboardingMenuItem = hasDeveloperOnboarding
44
- ? [
45
- <DropdownMenuItem
46
- key="my-apps"
47
- to="/apps"
48
- data-translation-key="userMenu.devOnboardingLabel"
49
- prefix={<GridIcon />}
50
- >
51
- {translate('userMenu.devOnboardingLabel')}
52
- </DropdownMenuItem>,
53
- ]
54
- : [];
55
-
56
42
  const menuItems = userMenu?.['menu'] || [];
57
43
 
58
44
  const customItems = menuItems.map((item) => (
59
45
  <DropdownMenuItem key={item.label} external={item.external} to={item.link || ''}>
60
- {item.label}
46
+ {item.labelTranslationKey ? translate(item.labelTranslationKey) : item.label}
61
47
  </DropdownMenuItem>
62
48
  ));
63
49
 
@@ -69,7 +55,6 @@ export function UserMenu({ className }: UserMenuProps) {
69
55
  key="userinfo"
70
56
  />,
71
57
  <DropdownMenuItem separatorLine={true} separator key="separator" />,
72
- ...devOnboardingMenuItem,
73
58
  ...customItems,
74
59
  <LogoutMenuItem key="logout" />,
75
60
  ];
@@ -84,4 +84,5 @@ export const useThemeHooks = jest.fn(() => ({
84
84
  useSubmitFeedback: jest.fn(() => ({
85
85
  submitFeedback: jest.fn(),
86
86
  })),
87
+ useLoadAndNavigate: jest.fn(),
87
88
  }));
@@ -64,7 +64,7 @@ export function useNestedMenu({ item, labelRef, nestedMenuRef }: NestedMenuProps
64
64
 
65
65
  const [firstChild] = item.items;
66
66
  if (!isExpanded && item.selectFirstItemOnExpand && firstChild.link) {
67
- await loadAndNavigate(navigate, firstChild.link);
67
+ await loadAndNavigate({ navigate, to: firstChild.link });
68
68
  }
69
69
  setIsExpanded(!isExpanded);
70
70
  }, [item, isExpanded, navigate, location.pathname, setIsExpanded]);
@@ -1,3 +1,5 @@
1
+ import { useNavigate } from 'react-router-dom';
2
+
1
3
  import type { L10nConfig } from '@redocly/theme/core/types';
2
4
 
3
5
  import { useThemeHooks } from '@redocly/theme/core/hooks';
@@ -8,8 +10,9 @@ export function useLanguagePicker(): {
8
10
  locales: L10nConfig['locales'];
9
11
  setLocale: (value: string) => void;
10
12
  } {
11
- const { useL10nConfig, usePreloadHistory } = useThemeHooks();
12
- const history = usePreloadHistory();
13
+ const { useL10nConfig, useLoadAndNavigate } = useThemeHooks();
14
+ const navigate = useNavigate();
15
+ const loadAndNavigate = useLoadAndNavigate();
13
16
  const { currentLocale, locales, defaultLocale } = useL10nConfig();
14
17
 
15
18
  const locale = locales.find((l) => l.code === currentLocale);
@@ -20,7 +23,7 @@ export function useLanguagePicker(): {
20
23
  );
21
24
 
22
25
  const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
23
- history.push(newUrlWithLanguage);
26
+ loadAndNavigate({ navigate, to: newUrlWithLanguage });
24
27
  }
25
28
 
26
29
  return {
@@ -1,16 +1,18 @@
1
+ import { useNavigate } from 'react-router-dom';
2
+
1
3
  import { useThemeHooks } from '@redocly/theme/core/hooks';
2
4
 
3
5
  export function useProductPicker() {
4
- const { useCurrentProduct, useProducts, usePreloadHistory, useTelemetry } = useThemeHooks();
6
+ const { useCurrentProduct, useProducts, useTelemetry, useLoadAndNavigate } = useThemeHooks();
5
7
  const currentProduct = useCurrentProduct();
6
8
  const products = useProducts();
7
9
  const telemetry = useTelemetry();
8
- const history = usePreloadHistory();
9
-
10
+ const navigate = useNavigate();
11
+ const loadAndNavigate = useLoadAndNavigate();
10
12
  function setProduct(product: typeof currentProduct) {
11
13
  if (!product) return;
12
14
  telemetry.send('product_picked', { product: product.slug });
13
- history.push(product.link);
15
+ loadAndNavigate({ navigate, to: product.link });
14
16
  }
15
17
  return {
16
18
  currentProduct,
@@ -1,6 +1,6 @@
1
1
  import type { PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
2
2
  import type { Callback, TFunction as TFunc } from 'i18next';
3
- import type { To, Location } from 'react-router-dom';
3
+ import type { To, Location, NavigateFunction } from 'react-router-dom';
4
4
  import type { CatalogConfig, ProductUiConfig } from '@redocly/theme/config';
5
5
  import type {
6
6
  UserMenuData,
@@ -121,6 +121,7 @@ export type ThemeHooks = {
121
121
  },
122
122
  ) => string;
123
123
  };
124
+ useLoadAndNavigate: () => (options: { navigate: NavigateFunction; to: string }) => Promise<void>;
124
125
  };
125
126
 
126
127
  export type L10nConfig = {
@@ -5,12 +5,18 @@ import { withLoadProgress } from '@redocly/theme/core/utils';
5
5
  export type HistoryOrigin = 'pm' | 'browser';
6
6
 
7
7
  let lastNavigatedPath;
8
- export async function loadAndNavigate(
9
- navigate: NavigateFunction,
10
- to: string,
11
- origin: HistoryOrigin = 'browser',
12
- options?: NavigateOptions,
13
- ) {
8
+ // this is copy from portal/src/client/app/utils/loadAndNavigate.ts, for case when we need to run Redoc without Realm
9
+ export async function loadAndNavigate({
10
+ navigate,
11
+ to,
12
+ origin = 'browser',
13
+ options,
14
+ }: {
15
+ navigate: NavigateFunction;
16
+ to: string;
17
+ origin?: HistoryOrigin;
18
+ options?: NavigateOptions;
19
+ }) {
14
20
  lastNavigatedPath = to;
15
21
  const { pathname, hash, search } = new URL(to, window.location.origin + window.location.pathname);
16
22
 
@@ -20,7 +26,7 @@ export async function loadAndNavigate(
20
26
  // @ts-ignore
21
27
  if (result?.redirectTo) {
22
28
  // @ts-ignore
23
- return loadAndNavigate(navigate, result.redirectTo, origin, options);
29
+ return loadAndNavigate({ navigate, to: result.redirectTo, origin, options });
24
30
  }
25
31
 
26
32
  if (result && lastNavigatedPath === to) {