@redocly/theme 0.70.0-next.3 → 0.70.0-next.4

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.
Files changed (96) hide show
  1. package/lib/components/Catalog/Catalog.js +1 -1
  2. package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
  3. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
  4. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
  5. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
  6. package/lib/components/Dropdown/Dropdown.js +3 -1
  7. package/lib/components/Markdown/Markdown.js +3 -2
  8. package/lib/components/Menu/Menu.js +4 -0
  9. package/lib/components/Menu/MenuSelect.d.ts +7 -0
  10. package/lib/components/Menu/MenuSelect.js +129 -0
  11. package/lib/components/Menu/variables.js +43 -4
  12. package/lib/components/Navbar/Navbar.js +44 -5
  13. package/lib/components/Navbar/variables.js +3 -0
  14. package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
  15. package/lib/components/NavigationTabs/NavigationTab.js +93 -0
  16. package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
  17. package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
  18. package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
  19. package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
  20. package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
  21. package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
  22. package/lib/components/NavigationTabs/variables.d.ts +1 -0
  23. package/lib/components/NavigationTabs/variables.js +37 -0
  24. package/lib/components/Search/SearchTrigger.js +8 -2
  25. package/lib/components/Sidebar/Sidebar.js +2 -2
  26. package/lib/components/TableOfContent/TableOfContent.js +2 -2
  27. package/lib/core/constants/common.d.ts +1 -0
  28. package/lib/core/constants/common.js +1 -0
  29. package/lib/core/hooks/index.d.ts +1 -0
  30. package/lib/core/hooks/index.js +1 -0
  31. package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
  32. package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
  33. package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
  34. package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
  35. package/lib/core/hooks/use-theme-hooks.js +2 -0
  36. package/lib/core/styles/global.js +12 -2
  37. package/lib/core/types/hooks.d.ts +5 -0
  38. package/lib/core/types/index.d.ts +1 -0
  39. package/lib/core/types/l10n.d.ts +1 -1
  40. package/lib/core/types/navigation-tabs.d.ts +49 -0
  41. package/lib/core/types/navigation-tabs.js +3 -0
  42. package/lib/core/utils/index.d.ts +1 -0
  43. package/lib/core/utils/index.js +1 -0
  44. package/lib/core/utils/menu.d.ts +4 -0
  45. package/lib/core/utils/menu.js +42 -3
  46. package/lib/core/utils/navigation-tabs.d.ts +8 -0
  47. package/lib/core/utils/navigation-tabs.js +71 -0
  48. package/lib/index.d.ts +5 -0
  49. package/lib/index.js +7 -1
  50. package/lib/layouts/PageLayout.js +1 -1
  51. package/lib/layouts/RootLayout.js +2 -2
  52. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
  53. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
  54. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
  55. package/package.json +3 -3
  56. package/src/components/Catalog/Catalog.tsx +1 -1
  57. package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
  58. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
  59. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
  60. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
  61. package/src/components/Dropdown/Dropdown.tsx +4 -1
  62. package/src/components/Markdown/Markdown.tsx +3 -2
  63. package/src/components/Menu/Menu.tsx +5 -0
  64. package/src/components/Menu/MenuSelect.tsx +198 -0
  65. package/src/components/Menu/variables.ts +43 -4
  66. package/src/components/Navbar/Navbar.tsx +22 -5
  67. package/src/components/Navbar/variables.ts +3 -0
  68. package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
  69. package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
  70. package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
  71. package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
  72. package/src/components/NavigationTabs/variables.ts +34 -0
  73. package/src/components/Search/SearchTrigger.tsx +11 -2
  74. package/src/components/Sidebar/Sidebar.tsx +2 -2
  75. package/src/components/TableOfContent/TableOfContent.tsx +2 -2
  76. package/src/core/constants/common.ts +1 -0
  77. package/src/core/hooks/__mocks__/use-theme-hooks.ts +2 -0
  78. package/src/core/hooks/index.ts +1 -0
  79. package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
  80. package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
  81. package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
  82. package/src/core/hooks/use-theme-hooks.ts +2 -0
  83. package/src/core/styles/global.ts +12 -2
  84. package/src/core/types/hooks.ts +5 -0
  85. package/src/core/types/index.ts +1 -0
  86. package/src/core/types/l10n.ts +3 -0
  87. package/src/core/types/navigation-tabs.ts +54 -0
  88. package/src/core/utils/index.ts +1 -0
  89. package/src/core/utils/menu.ts +49 -3
  90. package/src/core/utils/navigation-tabs.ts +99 -0
  91. package/src/index.ts +6 -0
  92. package/src/layouts/PageLayout.tsx +1 -1
  93. package/src/layouts/RootLayout.tsx +2 -2
  94. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
  95. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +3 -3
  96. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -1
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.NavigationTabs = NavigationTabs;
40
+ const react_1 = __importStar(require("react"));
41
+ const styled_components_1 = __importDefault(require("styled-components"));
42
+ const utils_1 = require("../../core/utils");
43
+ const hooks_1 = require("../../core/hooks");
44
+ const NavigationTab_1 = require("../../components/NavigationTabs/NavigationTab");
45
+ function NavigationTabs({ config, className }) {
46
+ var _a;
47
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
48
+ const { translate } = useTranslate();
49
+ const listRef = (0, react_1.useRef)(null);
50
+ const tabs = (_a = config === null || config === void 0 ? void 0 : config.items) !== null && _a !== void 0 ? _a : [];
51
+ const activeIndex = tabs.findIndex((tab) => tab.active);
52
+ (0, hooks_1.useScrollItemIntoView)(listRef, activeIndex);
53
+ if (!tabs.length) {
54
+ return null;
55
+ }
56
+ return (react_1.default.createElement(NavigationTabsWrapper, { "data-component-name": "NavigationTabs/NavigationTabs", className: className, "aria-label": translate('navigationTabs.label', 'Navigation tabs') },
57
+ react_1.default.createElement(NavigationTabsList, { ref: listRef }, tabs.map((tab, index) => (react_1.default.createElement(NavigationTab_1.NavigationTab, { key: `${tab.label}_${index}`, tab: tab }))))));
58
+ }
59
+ const NavigationTabsWrapper = styled_components_1.default.nav `
60
+ display: none;
61
+ box-sizing: border-box;
62
+ width: 100%;
63
+ height: var(--navigation-tabs-height);
64
+ max-width: var(--navbar-container-max-width);
65
+ padding: var(--navigation-tabs-padding);
66
+ background: var(--navigation-tabs-bg-color);
67
+ border-bottom: var(--navigation-tabs-bottom-border);
68
+ flex-shrink: 0;
69
+
70
+ @media screen and (min-width: ${utils_1.breakpoints.medium}) {
71
+ display: flex;
72
+ }
73
+
74
+ @media screen and (min-width: ${utils_1.breakpoints.max}) {
75
+ max-width: var(--container-max-width);
76
+ margin-left: auto;
77
+ margin-right: auto;
78
+ }
79
+ `;
80
+ const NavigationTabsList = styled_components_1.default.ul `
81
+ list-style: none;
82
+ margin: 0 0 calc(-1 * var(--navigation-tabs-border-width));
83
+ padding: 0;
84
+ display: flex;
85
+ flex-wrap: nowrap;
86
+ align-items: stretch;
87
+ gap: var(--navigation-tabs-gap);
88
+ min-width: 0;
89
+ overflow-x: auto;
90
+ scrollbar-width: none;
91
+ -ms-overflow-style: none;
92
+
93
+ &::-webkit-scrollbar {
94
+ display: none;
95
+ }
96
+ `;
97
+ //# sourceMappingURL=NavigationTabs.js.map
@@ -0,0 +1 @@
1
+ export declare const navigationTabs: import("styled-components").RuleSet<object>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.navigationTabs = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.navigationTabs = (0, styled_components_1.css) `
6
+ --navigation-tabs-height: 48px; // @presenter Spacing
7
+ --navigation-tabs-bg-color: transparent; // @presenter Color
8
+ --navigation-tabs-border-color: var(--border-color-secondary);
9
+ --navigation-tabs-border-width: 1px;
10
+ --navigation-tabs-bottom-border: var(--navigation-tabs-border-width) solid var(--navigation-tabs-border-color);
11
+ --navigation-tabs-padding-vertical: 0;
12
+ --navigation-tabs-padding-horizontal: var(--spacing-xl);
13
+ --navigation-tabs-padding: var(--navigation-tabs-padding-vertical) var(--navigation-tabs-padding-horizontal); // @presenter Spacing
14
+ --navigation-tabs-gap: var(--spacing-base); // @presenter Spacing
15
+
16
+ --navigation-tabs-item-padding-vertical: var(--spacing-xxs);
17
+ --navigation-tabs-item-padding-horizontal: 0;
18
+ --navigation-tabs-item-padding: var(--navigation-tabs-item-padding-vertical) var(--navigation-tabs-item-padding-horizontal);
19
+ --navigation-tabs-item-content-gap: var(--spacing-xs);
20
+ --navigation-tabs-item-font-size: var(--font-size-base);
21
+ --navigation-tabs-item-line-height: var(--line-height-base);
22
+ --navigation-tabs-item-font-weight: var(--font-weight-regular);
23
+ --navigation-tabs-item-font-weight-active: var(--font-weight-medium);
24
+ --navigation-tabs-item-text-color: var(--navbar-text-color); // @presenter Color
25
+ --navigation-tabs-item-text-color-hover: var(--text-color-primary); // @presenter Color
26
+ --navigation-tabs-item-text-color-active: var(--text-color-primary); // @presenter Color
27
+ --navigation-tabs-item-bottom-border: var(--navigation-tabs-border-width) solid transparent;
28
+ --navigation-tabs-item-bottom-border-hover: var(--navigation-tabs-border-width) solid var(--border-color-primary);
29
+ --navigation-tabs-item-bottom-border-active: var(--navigation-tabs-border-width) solid var(--border-color-inverse);
30
+ --navigation-tabs-item-border-color-focused: var(--button-border-color-focused);
31
+ --navigation-tabs-item-border-radius: var(--navbar-item-border-radius);
32
+ --navigation-tabs-item-icon-size: 1.25em; // @presenter Spacing
33
+ --navigation-tabs-item-external-icon-margin-left: 0;
34
+ --navigation-tabs-item-label-font-weight-active: var(--navigation-tabs-item-font-weight-active);
35
+ --navigation-tabs-item-transition: 150ms ease-in-out;
36
+ `;
37
+ //# sourceMappingURL=variables.js.map
@@ -61,13 +61,16 @@ function SearchTrigger({ onClick, className }) {
61
61
  }
62
62
  }
63
63
  mainShortcutKey = mainShortcutKey === null || mainShortcutKey === void 0 ? void 0 : mainShortcutKey.toUpperCase();
64
- const isMac = (0, utils_1.getUserAgent)().includes('Mac');
64
+ // A page can be cached and served to every platform, so the server renders a hidden
65
+ // placeholder and the browser picks the label after hydration.
66
+ const [isMac, setIsMac] = React.useState(undefined);
67
+ React.useEffect(() => setIsMac((0, utils_1.getUserAgent)().includes('Mac')), []);
65
68
  return (React.createElement(SearchTriggerWrapper, { onClick: onClick, className: className, "data-component-name": "Search/SearchTrigger" },
66
69
  React.createElement(SearchTriggerButton, { "data-testid": "search-trigger-button", variant: "text", size: "medium", icon: React.createElement(SearchIcon_1.SearchIcon, null), "aria-label": "Search trigger button" }),
67
70
  React.createElement(SearchTriggerInput, { "data-testid": "search-trigger-input", "data-translation-key": "search.navbar.label" },
68
71
  React.createElement(SearchIcon_1.SearchIcon, null),
69
72
  translate('search.navbar.label', 'Search'),
70
- mainShortcutKey === constants_1.DEFAULT_KEYBOARD_SHORTCUTS ? (React.createElement("span", null, isMac ? '⌘K' : 'Ctrl+K')) : (React.createElement("span", null, mainShortcutKey)))));
73
+ mainShortcutKey === constants_1.DEFAULT_KEYBOARD_SHORTCUTS ? (React.createElement(SearchTriggerShortcut, { $isPending: isMac === undefined }, isMac ? '⌘K' : 'Ctrl+K')) : (React.createElement("span", null, mainShortcutKey)))));
71
74
  }
72
75
  const SearchTriggerWrapper = styled_components_1.default.div `
73
76
  color: var(--search-trigger-color);
@@ -85,6 +88,9 @@ const SearchTriggerButton = (0, styled_components_1.default)(Button_1.Button) `
85
88
  display: none;
86
89
  }
87
90
  `;
91
+ const SearchTriggerShortcut = styled_components_1.default.span `
92
+ visibility: ${({ $isPending }) => ($isPending ? 'hidden' : 'visible')};
93
+ `;
88
94
  const SearchTriggerInput = styled_components_1.default.div `
89
95
  display: none;
90
96
  align-items: center;
@@ -38,8 +38,8 @@ const SidebarContent = styled_components_1.default.aside `
38
38
  flex-direction: column;
39
39
  width: 100%;
40
40
  -webkit-font-smoothing: antialiased;
41
- top: calc(var(--navbar-height) + var(--banner-height));
42
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
41
+ top: var(--navbar-offset);
42
+ height: calc(100vh - var(--navbar-offset));
43
43
  overflow-x: hidden;
44
44
  ${({ $opened }) => `
45
45
  display: ${$opened ? 'flex' : 'none'}
@@ -91,8 +91,8 @@ const TableOfContentHeader = styled_components_1.default.div `
91
91
  `;
92
92
  const TableOfContentItems = styled_components_1.default.div `
93
93
  position: sticky;
94
- top: calc(var(--navbar-height) + var(--toc-offset-top));
95
- max-height: calc(100vh - var(--navbar-height) - var(--toc-offset-top));
94
+ top: calc(var(--navbar-stack-height) + var(--toc-offset-top));
95
+ max-height: calc(100vh - var(--navbar-stack-height) - var(--toc-offset-top));
96
96
  overflow-y: auto;
97
97
  width: var(--toc-width);
98
98
  border-left: solid 1px var(--toc-border-color);
@@ -15,6 +15,7 @@ export declare enum FEEDBACK_TYPES {
15
15
  }
16
16
  export declare const DEFAULT_FEEDBACK_TYPE = FEEDBACK_TYPES.SENTIMENT;
17
17
  export declare enum MenuItemType {
18
+ Select = "select",
18
19
  Separator = "separator",
19
20
  DrillDown = "drilldown",
20
21
  Group = "group",
@@ -21,6 +21,7 @@ var FEEDBACK_TYPES;
21
21
  exports.DEFAULT_FEEDBACK_TYPE = FEEDBACK_TYPES.SENTIMENT;
22
22
  var MenuItemType;
23
23
  (function (MenuItemType) {
24
+ MenuItemType["Select"] = "select";
24
25
  MenuItemType["Separator"] = "separator";
25
26
  MenuItemType["DrillDown"] = "drilldown";
26
27
  MenuItemType["Group"] = "group";
@@ -58,3 +58,4 @@ export * from './use-toast-logic';
58
58
  export * from './use-banner-telemetry';
59
59
  export * from './use-tooltip-fallback-placement';
60
60
  export * from './use-anchor-positioning';
61
+ export * from './use-scroll-item-into-view';
@@ -74,4 +74,5 @@ __exportStar(require("./use-toast-logic"), exports);
74
74
  __exportStar(require("./use-banner-telemetry"), exports);
75
75
  __exportStar(require("./use-tooltip-fallback-placement"), exports);
76
76
  __exportStar(require("./use-anchor-positioning"), exports);
77
+ __exportStar(require("./use-scroll-item-into-view"), exports);
77
78
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMobileMenuItems = void 0;
4
+ const react_1 = require("react");
4
5
  const react_router_1 = require("react-router");
5
6
  const use_theme_hooks_1 = require("../use-theme-hooks");
6
7
  const use_theme_config_1 = require("../use-theme-config");
@@ -10,73 +11,96 @@ const MENU_SEPARATOR = {
10
11
  type: 'separator',
11
12
  separatorLine: true,
12
13
  };
14
+ const NO_VERSIONS = [];
15
+ const NO_NAV_ITEMS = [];
13
16
  const useMobileMenuItems = (menuType) => {
14
- var _a, _b, _c;
15
- const { useTranslate, useL10nConfig, useCurrentProduct, usePageVersions, useSidebarItems } = (0, use_theme_hooks_1.useThemeHooks)();
16
- const { versions = [] } = usePageVersions() || {};
17
+ var _a, _b, _c, _d;
18
+ var _e, _f, _g;
19
+ const { useTranslate, useL10nConfig, useCurrentProduct, usePageVersions, useSidebarItems, useNavigationTabs, } = (0, use_theme_hooks_1.useThemeHooks)();
20
+ const versions = (_e = (_a = usePageVersions()) === null || _a === void 0 ? void 0 : _a.versions) !== null && _e !== void 0 ? _e : NO_VERSIONS;
17
21
  const { defaultLocale, currentLocale, locales } = useL10nConfig();
18
22
  const { translate } = useTranslate();
19
23
  const activeVersion = versions.find((version) => version.active);
20
24
  const { currentItems: sidebarItems, pushDrilldownState, popDrilldownState, backLink, } = useSidebarItems(activeVersion);
25
+ const navigationTabs = useNavigationTabs();
21
26
  const location = (0, react_router_1.useLocation)();
22
27
  const currentProduct = useCurrentProduct();
23
- const hasProductNavbarOverride = (_a = currentProduct === null || currentProduct === void 0 ? void 0 : currentProduct.configOverride) === null || _a === void 0 ? void 0 : _a.navbar;
28
+ const hasProductNavbarOverride = (_b = currentProduct === null || currentProduct === void 0 ? void 0 : currentProduct.configOverride) === null || _b === void 0 ? void 0 : _b.navbar;
24
29
  const productThemeConfig = (0, use_theme_config_1.useThemeConfig)();
25
30
  const baseThemeConfig = (0, use_theme_config_1.useThemeConfig)(false);
26
- const baseNavItems = (((_b = baseThemeConfig.navbar) === null || _b === void 0 ? void 0 : _b.items) || []);
27
- const productNavItems = (hasProductNavbarOverride ? ((_c = productThemeConfig.navbar) === null || _c === void 0 ? void 0 : _c.items) || [] : []);
28
- const menuItems = [];
29
- if (menuType === common_1.MobileMenuType.PAGE) {
30
- if (activeVersion) {
31
- // eslint-disable-next-line no-warning-comments
32
- // TODO: consider to refactor
33
- const versionsSection = (0, menu_1.buildVersionSection)(translate, versions, activeVersion);
34
- menuItems.push(...versionsSection);
31
+ const baseNavItems = ((_f = (_c = baseThemeConfig.navbar) === null || _c === void 0 ? void 0 : _c.items) !== null && _f !== void 0 ? _f : NO_NAV_ITEMS);
32
+ const productNavItems = (hasProductNavbarOverride ? ((_g = (_d = productThemeConfig.navbar) === null || _d === void 0 ? void 0 : _d.items) !== null && _g !== void 0 ? _g : NO_NAV_ITEMS) : NO_NAV_ITEMS);
33
+ const products = baseThemeConfig.products;
34
+ const items = (0, react_1.useMemo)(() => {
35
+ const menuItems = [];
36
+ const navigationTabsSelect = menuType === common_1.MobileMenuType.PAGE ? (0, menu_1.buildNavigationTabsSelect)({ navigationTabs }) : undefined;
37
+ if (menuType === common_1.MobileMenuType.PAGE) {
38
+ if (activeVersion) {
39
+ menuItems.push(...(0, menu_1.buildVersionSection)(translate, versions, activeVersion));
40
+ }
41
+ if (menuItems.length && sidebarItems.length) {
42
+ menuItems.push(MENU_SEPARATOR);
43
+ }
44
+ menuItems.push(...sidebarItems);
35
45
  }
36
- if (menuItems.length && sidebarItems.length) {
37
- menuItems.push(MENU_SEPARATOR);
38
- }
39
- menuItems.push(...sidebarItems);
40
- }
41
- else if (menuType === common_1.MobileMenuType.PRODUCT) {
42
- menuItems.push(...productNavItems);
43
- if (menuItems.length && baseNavItems.length) {
44
- menuItems.push(MENU_SEPARATOR);
45
- }
46
- if (baseNavItems.length) {
47
- menuItems.push(...baseNavItems);
46
+ else if (menuType === common_1.MobileMenuType.PRODUCT) {
47
+ menuItems.push(...productNavItems);
48
+ if (menuItems.length && baseNavItems.length) {
49
+ menuItems.push(MENU_SEPARATOR);
50
+ }
51
+ if (baseNavItems.length) {
52
+ menuItems.push(...baseNavItems);
53
+ }
48
54
  }
49
- }
50
- else if (menuType === common_1.MobileMenuType.MAIN_MENU) {
51
- const productMenuItems = Object.values(baseThemeConfig.products || {}).map((product) => ({
52
- label: product.name,
53
- link: product.link,
54
- icon: product.icon,
55
- type: 'link',
56
- }));
57
- if (productMenuItems.length) {
58
- menuItems.push({
59
- type: 'separator',
60
- label: translate('mobileMenu.products', 'Products'),
61
- });
62
- menuItems.push(...productMenuItems);
55
+ else if (menuType === common_1.MobileMenuType.MAIN_MENU) {
56
+ const productMenuItems = Object.values(products || {}).map((product) => ({
57
+ label: product.name,
58
+ link: product.link,
59
+ icon: product.icon,
60
+ type: 'link',
61
+ }));
62
+ if (productMenuItems.length) {
63
+ menuItems.push({
64
+ type: 'separator',
65
+ label: translate('mobileMenu.products', 'Products'),
66
+ });
67
+ menuItems.push(...productMenuItems);
68
+ }
69
+ if (menuItems.length && baseNavItems.length) {
70
+ menuItems.push(MENU_SEPARATOR);
71
+ }
72
+ if (baseNavItems.length) {
73
+ menuItems.push(...baseNavItems);
74
+ }
63
75
  }
64
- if (menuItems.length && baseNavItems.length) {
76
+ const languagesMenu = (0, menu_1.buildLanguagesGroup)(locales, defaultLocale, currentLocale);
77
+ if (menuItems.length && languagesMenu) {
65
78
  menuItems.push(MENU_SEPARATOR);
66
79
  }
67
- if (baseNavItems.length) {
68
- menuItems.push(...baseNavItems);
80
+ if (languagesMenu) {
81
+ menuItems.push(languagesMenu);
69
82
  }
70
- }
71
- const languagesMenu = (0, menu_1.buildLanguagesGroup)(locales, defaultLocale, currentLocale);
72
- if (menuItems.length && languagesMenu) {
73
- menuItems.push(MENU_SEPARATOR);
74
- }
75
- if (languagesMenu) {
76
- menuItems.push(languagesMenu);
77
- }
83
+ return [
84
+ ...(navigationTabsSelect ? [navigationTabsSelect] : []),
85
+ ...(0, menu_1.mapNavbarItems)(menuItems, defaultLocale, currentLocale, locales, location),
86
+ ];
87
+ }, [
88
+ menuType,
89
+ navigationTabs,
90
+ activeVersion,
91
+ versions,
92
+ sidebarItems,
93
+ productNavItems,
94
+ baseNavItems,
95
+ products,
96
+ translate,
97
+ locales,
98
+ defaultLocale,
99
+ currentLocale,
100
+ location,
101
+ ]);
78
102
  return {
79
- items: (0, menu_1.mapNavbarItems)(menuItems, defaultLocale, currentLocale, locales, location),
103
+ items,
80
104
  popDrilldownState,
81
105
  pushDrilldownState,
82
106
  backLink,
@@ -7,31 +7,36 @@ const use_theme_hooks_1 = require("../use-theme-hooks");
7
7
  const use_theme_config_1 = require("../use-theme-config");
8
8
  const common_1 = require("../../constants/common");
9
9
  const useMobileMenuLevels = () => {
10
- var _a, _b;
11
- const { useTranslate, useCurrentProduct, usePageVersions, useSidebarItems } = (0, use_theme_hooks_1.useThemeHooks)();
10
+ var _a, _b, _c;
11
+ const { useTranslate, useCurrentProduct, usePageVersions, useSidebarItems, useNavigationTabs } = (0, use_theme_hooks_1.useThemeHooks)();
12
12
  const { versions = [] } = usePageVersions() || {};
13
13
  const activeVersion = versions.find((version) => version === null || version === void 0 ? void 0 : version.active);
14
14
  const { currentItems: sidebarItems } = useSidebarItems(activeVersion);
15
+ const navigationTabs = useNavigationTabs();
15
16
  const { translate } = useTranslate();
16
17
  const currentProduct = useCurrentProduct();
17
18
  const productThemeConfig = (0, use_theme_config_1.useThemeConfig)();
19
+ const baseThemeConfig = (0, use_theme_config_1.useThemeConfig)(false);
18
20
  const location = (0, react_router_1.useLocation)();
19
21
  const hasProductNavbarOverride = (_a = currentProduct === null || currentProduct === void 0 ? void 0 : currentProduct.configOverride) === null || _a === void 0 ? void 0 : _a.navbar;
20
22
  const productNavItems = (hasProductNavbarOverride ? ((_b = productThemeConfig.navbar) === null || _b === void 0 ? void 0 : _b.items) || [] : []);
23
+ const hasMainMenuItems = Object.values(baseThemeConfig.products || {}).length > 0 ||
24
+ (((_c = baseThemeConfig.navbar) === null || _c === void 0 ? void 0 : _c.items) || []).length > 0;
21
25
  const menuLevels = (0, react_1.useMemo)(() => {
22
- const menuLevels = [
23
- {
26
+ const menuLevels = [];
27
+ if (hasMainMenuItems) {
28
+ menuLevels.push({
24
29
  label: translate('mobileMenu.mainMenu', 'Main menu'),
25
30
  type: common_1.MobileMenuType.MAIN_MENU,
26
- },
27
- ];
31
+ });
32
+ }
28
33
  if (currentProduct && productNavItems.length) {
29
34
  menuLevels.push({
30
35
  label: currentProduct.name,
31
36
  type: common_1.MobileMenuType.PRODUCT,
32
37
  });
33
38
  }
34
- if (sidebarItems.length || activeVersion) {
39
+ if (sidebarItems.length || activeVersion || (navigationTabs === null || navigationTabs === void 0 ? void 0 : navigationTabs.tabs.length)) {
35
40
  menuLevels.push({
36
41
  label: translate('mobileMenu.previous', 'Previous'),
37
42
  type: common_1.MobileMenuType.PAGE,
@@ -0,0 +1,2 @@
1
+ import type { RefObject } from 'react';
2
+ export declare function useScrollItemIntoView(listRef: RefObject<HTMLElement | null>, activeIndex: number): void;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useScrollItemIntoView = useScrollItemIntoView;
4
+ const react_1 = require("react");
5
+ function useScrollItemIntoView(listRef, activeIndex) {
6
+ (0, react_1.useEffect)(() => {
7
+ const list = listRef.current;
8
+ const activeItem = activeIndex === -1 ? undefined : list === null || list === void 0 ? void 0 : list.children[activeIndex];
9
+ if (!list || !activeItem)
10
+ return;
11
+ const listRect = list.getBoundingClientRect();
12
+ const itemRect = activeItem.getBoundingClientRect();
13
+ list.scrollLeft += itemRect.left - listRect.left - (listRect.width - itemRect.width) / 2;
14
+ }, [listRef, activeIndex]);
15
+ }
16
+ //# sourceMappingURL=use-scroll-item-into-view.js.map
@@ -37,6 +37,8 @@ const fallbacks = {
37
37
  usePageProps: () => ({}),
38
38
  usePageSharedData: () => null,
39
39
  useMcpData: () => ({ docs: { enabled: false } }),
40
+ useSearchFeatures: () => ({}),
41
+ useNavigationTabs: () => undefined,
40
42
  };
41
43
  const useThemeHooks = () => {
42
44
  const context = (0, react_1.useContext)(ThemeDataContext_1.ThemeDataContext);
@@ -51,6 +51,8 @@ const variables_46 = require("../../components/PageActions/variables");
51
51
  const variables_47 = require("../../components/SvgViewer/variables");
52
52
  const variables_48 = require("../../components/Toast/variables");
53
53
  const variables_49 = require("../../components/PageNavigation/variables");
54
+ const variables_50 = require("../../components/NavigationTabs/variables");
55
+ const utils_1 = require("../../core/utils");
54
56
  const palette_1 = require("./palette");
55
57
  const dark_1 = require("./dark");
56
58
  const themeColors = (0, styled_components_1.css) `
@@ -1112,8 +1114,8 @@ const error = (0, styled_components_1.css) `
1112
1114
  --detailed-error-overlay-z-index: var(--z-index-raised);
1113
1115
 
1114
1116
  --detailed-error-modal-width: calc(100% - var(--spacing-lg) * 2);
1115
- --detailed-error-modal-height: calc(100vh - var(--navbar-height) - var(--spacing-lg) * 2);
1116
- --detailed-error-modal-top: calc(var(--spacing-lg) + var(--navbar-height));
1117
+ --detailed-error-modal-height: calc(100vh - var(--navbar-stack-height) - var(--spacing-lg) * 2);
1118
+ --detailed-error-modal-top: calc(var(--spacing-lg) + var(--navbar-stack-height));
1117
1119
  --detailed-error-modal-border-radius: var(--border-radius-md);
1118
1120
  --detailed-error-modal-bg-color: var(--bg-color-raised);
1119
1121
  --detailed-error-modal-color: var(--text-color-primary);
@@ -1350,6 +1352,7 @@ exports.styles = (0, styled_components_1.css) `
1350
1352
  ${variables_26.productPicker}
1351
1353
  ${variables_12.responsePanelColors}
1352
1354
  ${variables_23.search}
1355
+ ${variables_50.navigationTabs}
1353
1356
  ${variables_14.select}
1354
1357
  ${variables_4.sidebar}
1355
1358
  ${sizeAndSpace}
@@ -1390,6 +1393,13 @@ exports.styles = (0, styled_components_1.css) `
1390
1393
  ${dark_1.darkMode};
1391
1394
  }
1392
1395
 
1396
+ @media screen and (min-width: ${utils_1.breakpoints.medium}) {
1397
+ :root:has([data-component-name='NavigationTabs/NavigationTabs']) {
1398
+ --navbar-stack-height: calc(var(--navbar-height) + var(--navigation-tabs-height, 48px));
1399
+ --navbar-row-bottom-border-color: transparent;
1400
+ }
1401
+ }
1402
+
1393
1403
  :root.notransition * {
1394
1404
  transition: none !important;
1395
1405
  }
@@ -8,6 +8,7 @@ import type { CatalogConfig, ProductUiConfig } from '../../config';
8
8
  import type { UseCatalogResponse, FilteredCatalog, UseCatalogSortResponse, UseCatalogSearchResponse, UseCatalogProps, CatalogApiParams, CatalogApiResults, BffCatalogEntity, BffCatalogEntityList, BffCatalogRelatedEntity, BffCatalogRelatedEntityList, BffCatalogEntityRevision, BffCatalogEntityRevisionList } from './catalog';
9
9
  import type { UserMenuData } from './user-menu';
10
10
  import type { ItemState, DrilldownMenuItemDetails } from './sidebar';
11
+ import type { NavigationTabsState } from './navigation-tabs';
11
12
  import type { SearchItemData, SearchFacet, SearchFilterItem, SearchFacetQuery, AiSearchConversationItem, ContentSegment, ToolCall } from './search';
12
13
  import type { SubmitFeedbackParams } from './feedback';
13
14
  import type { TFunction } from './l10n';
@@ -85,6 +86,9 @@ export type ThemeHooks = {
85
86
  askAi?: boolean;
86
87
  retrySearch: () => Promise<void>;
87
88
  };
89
+ useSearchFeatures: () => {
90
+ askAi?: boolean;
91
+ };
88
92
  useAiSearch: (options?: {
89
93
  filter?: SearchFilterItem[];
90
94
  product?: string;
@@ -128,6 +132,7 @@ export type ThemeHooks = {
128
132
  label?: string;
129
133
  };
130
134
  };
135
+ useNavigationTabs: () => NavigationTabsState | undefined;
131
136
  useSidebarSiblingsData: () => {
132
137
  prevPage?: ResolvedNavItemWithLink;
133
138
  nextPage?: ResolvedNavItemWithLink;
@@ -7,6 +7,7 @@ export type * from './feedback';
7
7
  export type * from './hooks';
8
8
  export type * from './markdown';
9
9
  export type * from './navbar';
10
+ export type * from './navigation-tabs';
10
11
  export * from './search';
11
12
  export type * from './select';
12
13
  export type * from './sidebar';