@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
@@ -151,7 +151,7 @@ const CatalogDescription = styled_components_1.default.p `
151
151
  const CatalogPageWrapper = styled_components_1.default.div `
152
152
  --sidebar-width: var(--catalog-sidebar-width);
153
153
 
154
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
154
+ height: calc(100vh - var(--navbar-offset));
155
155
  display: flex;
156
156
  flex-direction: column;
157
157
  overflow: hidden;
@@ -142,10 +142,10 @@ function CatalogEntityHistorySidebar({ entityKey, revision, version, className,
142
142
  }
143
143
  const SidebarOverlay = styled_components_1.default.div `
144
144
  position: fixed;
145
- top: calc(var(--navbar-height) + var(--banner-height));
145
+ top: var(--navbar-offset);
146
146
  left: 0;
147
147
  width: var(--sidebar-width);
148
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
148
+ height: calc(100vh - var(--navbar-offset));
149
149
  padding: var(--catalog-history-sidebar-padding);
150
150
  background-color: var(--catalog-history-sidebar-bg-color);
151
151
  border-right: 1px solid var(--catalog-history-sidebar-border-color);
@@ -98,7 +98,7 @@ const SplitViewWrapper = styled_components_1.default.div `
98
98
  const SchemaSampleWrapper = styled_components_1.default.div `
99
99
  flex: 1;
100
100
  position: sticky;
101
- top: calc(var(--navbar-height) + var(--banner-height) + var(--spacing-md));
101
+ top: calc(var(--navbar-offset) + var(--spacing-md));
102
102
  align-self: flex-start;
103
103
  padding-top: var(--spacing-sm);
104
104
  `;
@@ -14,7 +14,7 @@ function CatalogMobileFiltersPanel({ setMobileFiltersPanelOpen, filterContent, }
14
14
  }
15
15
  const CatalogMobileFiltersPanelWrapper = styled_components_1.default.div `
16
16
  width: 100%;
17
- max-height: calc(100vh - var(--navbar-height) - var(--banner-height));
17
+ max-height: calc(100vh - var(--navbar-offset));
18
18
  overflow-y: auto;
19
19
  background: var(--sidebar-bg-color);
20
20
  display: flex;
@@ -15,10 +15,10 @@ function CatalogMobileFiltersPanelOverlay({ setMobileFiltersPanelOpen, filterCon
15
15
  const CatalogMobileFiltersPanelOverlayWrapper = styled_components_1.default.div `
16
16
  display: none;
17
17
  position: fixed;
18
- top: calc(var(--navbar-height) + var(--banner-height));
18
+ top: var(--navbar-offset);
19
19
  left: 0;
20
20
  width: 100%;
21
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
21
+ height: calc(100vh - var(--navbar-offset));
22
22
  z-index: 3;
23
23
  background: var(--bg-color);
24
24
  flex-direction: column;
@@ -42,6 +42,7 @@ const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon")
42
42
  const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
43
43
  const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect;
44
44
  exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, portalled = false, onClick, onClose, onOpen, }, ref) => {
45
+ var _a, _b;
45
46
  const dropdownRef = (0, react_1.useRef)(null);
46
47
  const menuRef = (0, react_1.useRef)(null);
47
48
  const [isOpen, setIsOpen] = (0, hooks_1.useControlledState)(false, active);
@@ -120,7 +121,8 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
120
121
  (0, hooks_1.useOutsideClick)(portalled ? [wrapperRef, menuRef] : wrapperRef, handleClose);
121
122
  const menuContent = typeof children === 'function' ? children({ close: handleClose, isOpen }) : children;
122
123
  const triggerChild = react_1.default.Children.only(trigger);
123
- const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, 'aria-expanded': isOpen, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined }));
124
+ const isLinkTrigger = Boolean(((_a = triggerChild.props) === null || _a === void 0 ? void 0 : _a.to) || ((_b = triggerChild.props) === null || _b === void 0 ? void 0 : _b.href));
125
+ const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, 'aria-haspopup': 'menu', 'aria-expanded': isOpen, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' || !isLinkTrigger ? handleKeyDown : undefined }));
124
126
  const menu = (react_1.default.createElement(ChildrenWrapper, { ref: menuRef, $placement: placement, $alignment: alignment, $isOpen: isOpen, $portalled: portalled, style: portalled ? menuStyle : undefined, onClick: closeOnClick ? handleChildClick : undefined }, menuContent));
125
127
  const portalledMenu = isOpen && typeof document !== 'undefined' ? (0, react_dom_1.createPortal)(menu, document.body) : null;
126
128
  return (react_1.default.createElement(DropdownWrapper, Object.assign({ "data-component-name": "Dropdown/Dropdown", "data-testid": "dropdown" }, dataAttributes, { className: className, ref: wrapperRef, onPointerEnter: triggerEvent === 'hover' ? handleOpen : undefined, onPointerLeave: triggerEvent === 'hover' ? handleClose : undefined, onClick: onClick }),
@@ -82,7 +82,7 @@ exports.Markdown = styled_components_1.default.main
82
82
  ${links_1.markdownLinksCss}
83
83
 
84
84
  a[name], [id] {
85
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
85
+ scroll-margin-top: var(--navbar-offset);
86
86
  }
87
87
 
88
88
  img,
@@ -95,7 +95,7 @@ exports.Markdown = styled_components_1.default.main
95
95
  font-family: var(--heading-font-family);
96
96
  position: relative;
97
97
 
98
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
98
+ scroll-margin-top: var(--navbar-offset);
99
99
  ${(0, heading_anchor_1.headingAnchorCss)(constants_1.ANCHOR_CLASS)};
100
100
 
101
101
  h1,
@@ -306,6 +306,7 @@ exports.Markdown = styled_components_1.default.main
306
306
  font-size: inherit;
307
307
  font-family: inherit;
308
308
  border: none;
309
+ padding: 0;
309
310
  }
310
311
  }
311
312
 
@@ -7,12 +7,16 @@ exports.Menu = Menu;
7
7
  const styled_components_1 = __importDefault(require("styled-components"));
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const MenuItem_1 = require("../../components/Menu/MenuItem");
10
+ const MenuSelect_1 = require("../../components/Menu/MenuSelect");
10
11
  const constants_1 = require("../../core/constants");
11
12
  const utils_1 = require("../../core/utils");
12
13
  function Menu({ depth = 0, items, className, isMobile, onDrilldownOpen, }) {
13
14
  const activeItem = items.find(({ active }) => active);
14
15
  return (react_1.default.createElement(MenuWrapper, { className: className, "data-component-name": "Menu/Menu" }, items.map((item, index) => {
15
16
  var _a;
17
+ if ((0, utils_1.getMenuItemType)(item) === constants_1.MenuItemType.Select) {
18
+ return react_1.default.createElement(MenuSelect_1.MenuSelect, { item: item, key: `${item.label}-${index}` });
19
+ }
16
20
  return (react_1.default.createElement(MenuItem_1.MenuItem, { item: item, key: `${item.link || item.label}-${index}`, activeItem: activeItem, isMobile: isMobile, depth: depth, onClick: () => {
17
21
  if ((0, utils_1.getMenuItemType)(item) === constants_1.MenuItemType.DrillDown) {
18
22
  onDrilldownOpen === null || onDrilldownOpen === void 0 ? void 0 : onDrilldownOpen({ previousLink: activeItem === null || activeItem === void 0 ? void 0 : activeItem.link, item });
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { ItemState } from '../../core/types';
3
+ export type MenuSelectProps = {
4
+ item: ItemState;
5
+ className?: string;
6
+ };
7
+ export declare function MenuSelect({ item, className }: MenuSelectProps): JSX.Element;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MenuSelect = MenuSelect;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const hooks_1 = require("../../core/hooks");
11
+ const Dropdown_1 = require("../../components/Dropdown/Dropdown");
12
+ const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
13
+ const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
14
+ const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
15
+ const LaunchIcon_1 = require("../../icons/LaunchIcon/LaunchIcon");
16
+ const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
17
+ const CheckmarkIcon_1 = require("../../icons/CheckmarkIcon/CheckmarkIcon");
18
+ function MenuSelect({ item, className }) {
19
+ const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
20
+ const { translate } = useTranslate();
21
+ const telemetry = useTelemetry();
22
+ return (react_1.default.createElement(MenuSelectWrapper, { "data-component-name": "Menu/MenuSelect", className: className, role: "listitem" },
23
+ react_1.default.createElement(MenuSelectDropdown, { alignment: "start", trigger: react_1.default.createElement(MenuSelectTrigger, { type: "button" },
24
+ react_1.default.createElement(MenuSelectLabel, null, translate(item.labelTranslationKey, item.label)),
25
+ react_1.default.createElement(MenuSelectChevron, { size: "var(--menu-select-icon-size)", color: "--menu-select-icon-color" })) },
26
+ react_1.default.createElement(MenuSelectMenu, null, item.items.map((option, index) => {
27
+ const key = `${option.link || option.label}-${index}`;
28
+ const checkmark = option.active ? (react_1.default.createElement(MenuSelectCheckmark, { size: "var(--menu-select-option-checkmark-size)" })) : null;
29
+ const content = (react_1.default.createElement(MenuSelectOptionContent, { $active: option.active },
30
+ option.icon || option.srcSet ? (react_1.default.createElement(MenuSelectOptionIcon, { icon: option.icon, srcSet: option.srcSet })) : null,
31
+ translate(option.labelTranslationKey, option.label),
32
+ option.external ? (react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "var(--menu-select-option-external-icon-size)" })) : null));
33
+ if (!option.link) {
34
+ return (react_1.default.createElement(MenuSelectOption, { key: key, active: option.active, prefix: checkmark, dataAttributes: { 'aria-disabled': 'true' } }, content));
35
+ }
36
+ return (react_1.default.createElement(MenuSelectOption, { key: key, to: option.link, external: option.external, target: option.target === '_blank' ? '_blank' : undefined, active: option.active, "aria-current": option.active ? 'page' : undefined, prefix: checkmark, onAction: () => telemetry.sendSidebarItemClickedMessage([
37
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('sidebarItem', 'sidebar')), { label: option.label, type: 'link' }),
38
+ ]) }, content));
39
+ })))));
40
+ }
41
+ const MenuSelectWrapper = styled_components_1.default.div `
42
+ margin: var(--menu-select-margin);
43
+ `;
44
+ const MenuSelectDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
45
+ --dropdown-menu-padding-top: var(--menu-select-menu-offset);
46
+ --dropdown-menu-padding: var(--menu-select-menu-padding);
47
+ --dropdown-menu-border-radius: var(--menu-select-menu-border-radius);
48
+ --dropdown-menu-item-gap: var(--menu-select-option-gap);
49
+ --dropdown-menu-item-border-radius: var(--menu-select-option-border-radius);
50
+ --dropdown-menu-item-bg-color-active: var(--menu-select-option-bg-color-active);
51
+ --dropdown-menu-item-color-active: var(--menu-select-option-text-color-active);
52
+
53
+ width: 100%;
54
+
55
+ > * {
56
+ min-width: 100%;
57
+ }
58
+ `;
59
+ const MenuSelectChevron = (0, styled_components_1.default)(ChevronDownIcon_1.ChevronDownIcon) `
60
+ transition: var(--menu-select-transition);
61
+ `;
62
+ const MenuSelectTrigger = styled_components_1.default.button `
63
+ display: flex;
64
+ align-items: center;
65
+ gap: var(--menu-select-gap);
66
+ box-sizing: border-box;
67
+ width: 100%;
68
+ height: var(--menu-select-height);
69
+ padding: 0 var(--menu-select-padding-horizontal);
70
+ border: var(--menu-select-border);
71
+ border-radius: var(--menu-select-border-radius);
72
+ background-color: var(--menu-select-bg-color);
73
+ color: var(--menu-select-text-color);
74
+ font-family: inherit;
75
+ font-size: var(--menu-select-font-size);
76
+ line-height: var(--menu-select-line-height);
77
+ text-align: left;
78
+ cursor: pointer;
79
+
80
+ &:focus-visible {
81
+ outline: 1px solid var(--menu-select-border-color-focused);
82
+ }
83
+
84
+ &[aria-expanded='true'] ${MenuSelectChevron} {
85
+ transform: rotate(180deg);
86
+ }
87
+ `;
88
+ const MenuSelectLabel = styled_components_1.default.span `
89
+ flex: 1;
90
+ min-width: 0;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ white-space: nowrap;
94
+ `;
95
+ const MenuSelectMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
96
+ box-sizing: border-box;
97
+ width: 100%;
98
+ max-width: 100%;
99
+ `;
100
+ const MenuSelectOption = (0, styled_components_1.default)(DropdownMenuItem_1.DropdownMenuItem) `
101
+ position: relative;
102
+ box-sizing: border-box;
103
+ padding: var(--menu-select-option-padding);
104
+
105
+ &[aria-disabled='true'] {
106
+ cursor: default;
107
+ pointer-events: none;
108
+ }
109
+ `;
110
+ const MenuSelectCheckmark = (0, styled_components_1.default)(CheckmarkIcon_1.CheckmarkIcon) `
111
+ position: absolute;
112
+ top: 50%;
113
+ left: var(--menu-select-option-checkmark-offset);
114
+ transform: translateY(-50%);
115
+ `;
116
+ const MenuSelectOptionContent = styled_components_1.default.span `
117
+ display: inline-flex;
118
+ align-items: center;
119
+ gap: var(--menu-select-option-content-gap);
120
+ font-weight: ${({ $active }) => $active
121
+ ? 'var(--menu-select-option-font-weight-active)'
122
+ : 'var(--menu-select-option-font-weight)'};
123
+ `;
124
+ const MenuSelectOptionIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
125
+ --icon-width: var(--menu-select-option-icon-size);
126
+ --icon-height: var(--menu-select-option-icon-size);
127
+ flex-shrink: 0;
128
+ `;
129
+ //# sourceMappingURL=MenuSelect.js.map
@@ -104,6 +104,45 @@ exports.menu = (0, styled_components_1.css) `
104
104
  --menu-back-button-gap: var(--spacing-xs);
105
105
  --menu-back-button-icon: none;
106
106
 
107
+ /**
108
+ * @tokens Menu select
109
+ */
110
+ --menu-select-margin-top: 0;
111
+ --menu-select-margin-bottom: var(--spacing-xs);
112
+ --menu-select-margin-horizontal: var(--menu-item-label-margin-horizontal);
113
+ --menu-select-margin: var(--menu-select-margin-top) var(--menu-select-margin-horizontal) var(--menu-select-margin-bottom); // @presenter Spacing
114
+ --menu-select-height: 32px; // @presenter Spacing
115
+ --menu-select-padding-horizontal: calc(var(--spacing-sm) - var(--border-width)); // @presenter Spacing
116
+ --menu-select-gap: var(--spacing-xxs); // @presenter Spacing
117
+ --menu-select-font-size: var(--font-size-base); // @presenter FontSize
118
+ --menu-select-line-height: var(--line-height-base); // @presenter LineHeight
119
+ --menu-select-text-color: var(--input-content-color-active); // @presenter Color
120
+ --menu-select-bg-color: var(--input-bg-color); // @presenter Color
121
+ --menu-select-border: var(--input-border); // @presenter Border
122
+ --menu-select-border-color-focused: var(--input-border-color-focused); // @presenter Color
123
+ --menu-select-border-radius: var(--input-border-radius); // @presenter BorderRadius
124
+ --menu-select-icon-size: 16px;
125
+ --menu-select-icon-color: var(--icon-color-secondary); // @presenter Color
126
+ --menu-select-transition: transform 150ms ease-in-out;
127
+ --menu-select-menu-offset: var(--spacing-xs); // @presenter Spacing
128
+ --menu-select-menu-padding: calc(var(--dropdown-menu-padding) - var(--border-width)); // @presenter Spacing
129
+ --menu-select-menu-border-radius: var(--border-radius-lg); // @presenter BorderRadius
130
+ --menu-select-option-gap: calc(var(--spacing-unit) / 2); // @presenter Spacing
131
+ --menu-select-option-content-gap: var(--spacing-xs); // @presenter Spacing
132
+ --menu-select-option-padding-vertical: var(--dropdown-menu-item-padding-vertical);
133
+ --menu-select-option-padding-left: var(--spacing-md);
134
+ --menu-select-option-padding-right: var(--spacing-sm);
135
+ --menu-select-option-padding: var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-right) var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-left); // @presenter Spacing
136
+ --menu-select-option-border-radius: var(--border-radius-md); // @presenter BorderRadius
137
+ --menu-select-option-font-weight: var(--font-weight-regular); // @presenter FontWeight
138
+ --menu-select-option-font-weight-active: var(--font-weight-medium); // @presenter FontWeight
139
+ --menu-select-option-text-color-active: var(--text-color-primary); // @presenter Color
140
+ --menu-select-option-bg-color-active: transparent; // @presenter Color
141
+ --menu-select-option-icon-size: var(--menu-item-icon-size);
142
+ --menu-select-option-external-icon-size: var(--menu-item-external-icon-size);
143
+ --menu-select-option-checkmark-size: 14px;
144
+ --menu-select-option-checkmark-offset: calc((var(--menu-select-option-padding-left) - var(--menu-select-option-checkmark-size)) / 2);
145
+
107
146
  /**
108
147
  * @tokens Menu items
109
148
  */
@@ -134,18 +173,18 @@ exports.mobileMenu = (0, styled_components_1.css) `
134
173
  * @tokens Mobile Menu
135
174
  * */
136
175
  /* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
137
- --menu-mobile-height: calc(100vh - var(--navbar-height) - var(--banner-height));
138
- --menu-mobile-height: calc(100dvh - var(--navbar-height) - var(--banner-height));
176
+ --menu-mobile-height: calc(100vh - var(--navbar-offset));
177
+ --menu-mobile-height: calc(100dvh - var(--navbar-offset));
139
178
  --menu-mobile-width: 100%;
140
179
  --menu-mobile-z-index: var(--z-index-raised);
141
180
  --menu-mobile-left: 0;
142
- --menu-mobile-top: calc(var(--navbar-height) + var(--banner-height));
181
+ --menu-mobile-top: var(--navbar-offset);
143
182
  --menu-mobile-transition: 0.5s;
144
183
  --menu-mobile-bg: var(--bg-color); // @presenter Color
145
184
  --menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
146
185
  --menu-mobile-line-height: var(--line-height-base); // @presenter LineHeight
147
186
  --menu-mobile-padding-top: var(--spacing-sm); // @presenter Spacing
148
- --menu-mobile-margin-horizontal: var(--spacing-xs); // @presenter Spacing
187
+ --menu-mobile-margin-horizontal: 0; // @presenter Spacing
149
188
  --menu-mobile-items-margin-top: var(--spacing-xxs); // @presenter Spacing
150
189
 
151
190
  --menu-mobile-profile-bg-color: var(--bg-color); // @presenter Color
@@ -1,15 +1,49 @@
1
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
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.Navbar = Navbar;
7
- const react_1 = __importDefault(require("react"));
40
+ const react_1 = __importStar(require("react"));
8
41
  const styled_components_1 = __importDefault(require("styled-components"));
9
42
  const utils_1 = require("../../core/utils");
10
43
  const hooks_1 = require("../../core/hooks");
11
44
  const NavbarLogo_1 = require("../../components/Navbar/NavbarLogo");
12
45
  const NavbarMenu_1 = require("../../components/Navbar/NavbarMenu");
46
+ const NavigationTabs_1 = require("../../components/NavigationTabs/NavigationTabs");
13
47
  const MenuMobile_1 = require("../../components/Menu/MenuMobile");
14
48
  const ColorModeSwitcher_1 = require("../../components/ColorModeSwitcher/ColorModeSwitcher");
15
49
  const Search_1 = require("../../components/Search/Search");
@@ -24,9 +58,12 @@ function Navbar({ className }) {
24
58
  var _a;
25
59
  const { isOpen, closeMobileMenu, openMobileMenu } = (0, hooks_1.useMobileMenu)(false);
26
60
  const themeConfig = (0, hooks_1.useThemeConfig)();
27
- const { useL10n, useTelemetry } = (0, hooks_1.useThemeHooks)();
61
+ const { useL10n, useTelemetry, useTranslate, useNavigationTabs } = (0, hooks_1.useThemeHooks)();
28
62
  const { changeLanguage } = useL10n();
63
+ const { translate } = useTranslate();
29
64
  const telemetry = useTelemetry();
65
+ const navigationTabs = useNavigationTabs();
66
+ const navigationTabsConfig = (0, react_1.useMemo)(() => (0, utils_1.toNavigationTabsConfig)({ state: navigationTabs }), [navigationTabs]);
30
67
  const menu = (_a = themeConfig.navbar) === null || _a === void 0 ? void 0 : _a.items;
31
68
  const { search: searchSettings, navbar, userMenu: userMenuSettings, logo } = themeConfig;
32
69
  if (navbar === null || navbar === void 0 ? void 0 : navbar.hide) {
@@ -34,7 +71,7 @@ function Navbar({ className }) {
34
71
  }
35
72
  const hideSearch = (searchSettings === null || searchSettings === void 0 ? void 0 : searchSettings.hide) || ((searchSettings === null || searchSettings === void 0 ? void 0 : searchSettings.placement) && (searchSettings === null || searchSettings === void 0 ? void 0 : searchSettings.placement) !== 'navbar');
36
73
  const hideUserMenu = userMenuSettings === null || userMenuSettings === void 0 ? void 0 : userMenuSettings.hide;
37
- return (react_1.default.createElement(NavbarWrapper, { "data-component-name": "Navbar/Navbar", className: className },
74
+ return (react_1.default.createElement(NavbarWrapper, { "data-component-name": "Navbar/Navbar", className: className, "aria-label": translate('navbar.label', 'Main navigation') },
38
75
  react_1.default.createElement(Banner_1.Banner, null),
39
76
  isOpen && react_1.default.createElement(MenuMobile_1.MenuMobile, { hideUserProfile: !!hideUserMenu }),
40
77
  react_1.default.createElement(NavbarRow, null,
@@ -57,11 +94,12 @@ function Navbar({ className }) {
57
94
  (0, utils_1.getBaseDataAttributes)('mobileMenuOpen', 'button'),
58
95
  ]);
59
96
  }, icon: isOpen ? react_1.default.createElement(CloseIcon_1.CloseIcon, null) : react_1.default.createElement(MenuIcon_1.MenuIcon, null), "aria-label": isOpen ? 'Close menu button' : 'Open menu button' }),
60
- hideUserMenu ? null : react_1.default.createElement(UserMenu_1.UserMenu, null))));
97
+ hideUserMenu ? null : react_1.default.createElement(UserMenu_1.UserMenu, null)),
98
+ navigationTabsConfig && react_1.default.createElement(NavigationTabs_1.NavigationTabs, { config: navigationTabsConfig })));
61
99
  }
62
100
  const NavbarWrapper = styled_components_1.default.nav `
63
101
  --text-color: var(--navbar-text-color);
64
- height: calc(var(--navbar-height) + var(--banner-height));
102
+ height: var(--navbar-offset, calc(var(--navbar-height) + var(--banner-height)));
65
103
  transition: height 0.4s ease-out;
66
104
 
67
105
  position: sticky;
@@ -101,6 +139,7 @@ const NavbarRow = styled_components_1.default.div `
101
139
  box-sizing: border-box;
102
140
  margin-top: var(--banner-height);
103
141
  transition: margin-top 0.5s ease-out;
142
+ border-bottom-color: var(--navbar-row-bottom-border-color, var(--navbar-border-color));
104
143
 
105
144
  @media screen and (min-width: ${utils_1.breakpoints.max}) {
106
145
  max-width: var(--container-max-width);
@@ -6,9 +6,12 @@ exports.navbar = (0, styled_components_1.css) `
6
6
  --navbar-bg-color: var(--bg-color); // @presenter Color
7
7
  --navbar-border-color: var(--border-color-secondary);
8
8
  --navbar-border: 1px solid var(--navbar-border-color);
9
+ --navbar-row-bottom-border-color: var(--navbar-border-color);
9
10
 
10
11
  --navbar-text-color: var(--text-color-secondary); // @presenter Color
11
12
  --navbar-height: 64px; // @presenter Spacing
13
+ --navbar-stack-height: var(--navbar-height);
14
+ --navbar-offset: calc(var(--navbar-stack-height) + var(--banner-height));
12
15
  --navbar-font-size: var(--font-size-base);
13
16
  --navbar-padding: 0 var(--spacing-xl); // @presenter Spacing
14
17
  --navbar-font-family: var(--font-family-base);
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { NavigationTabRowItem } from '../../core/types';
3
+ export type NavigationTabProps = {
4
+ tab: NavigationTabRowItem;
5
+ className?: string;
6
+ };
7
+ export declare function NavigationTab({ tab, className }: NavigationTabProps): JSX.Element | null;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NavigationTab = NavigationTab;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const hooks_1 = require("../../core/hooks");
11
+ const Link_1 = require("../../components/Link/Link");
12
+ const Dropdown_1 = require("../../components/Dropdown/Dropdown");
13
+ const NavigationTabMenu_1 = require("../../components/NavigationTabs/NavigationTabMenu");
14
+ const NavigationTabContent_1 = require("../../components/NavigationTabs/NavigationTabContent");
15
+ const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
16
+ function NavigationTab({ tab, className }) {
17
+ const { useTelemetry } = (0, hooks_1.useThemeHooks)();
18
+ const telemetry = useTelemetry();
19
+ const active = !!tab.active;
20
+ const menuItems = tab.type === 'group' ? tab.items : [];
21
+ const isGroup = tab.type === 'group' && menuItems.length > 0;
22
+ const linkItem = tab.type === 'link' ? tab : undefined;
23
+ if (!(linkItem === null || linkItem === void 0 ? void 0 : linkItem.link) && !isGroup) {
24
+ return null;
25
+ }
26
+ const content = (react_1.default.createElement(react_1.default.Fragment, null,
27
+ react_1.default.createElement(NavigationTabContent_1.NavigationTabContent, { item: tab }),
28
+ isGroup ? react_1.default.createElement(NavigationTabChevron, { size: "10px" }) : null));
29
+ if (isGroup) {
30
+ return (react_1.default.createElement(NavigationTabWrapper, { "data-component-name": "NavigationTabs/NavigationTab", className: className },
31
+ react_1.default.createElement(NavigationTabDropdown, { triggerEvent: "hover", portalled: true, trigger: react_1.default.createElement(NavigationTabTrigger, { $active: active, "aria-current": active ? 'true' : undefined, onClick: () => telemetry.sendNavbarMenuItemClickedMessage((0, utils_1.getNavbarItemClickedPayload)(tab.type)) }, content) },
32
+ react_1.default.createElement(NavigationTabMenu_1.NavigationTabMenu, { items: menuItems }))));
33
+ }
34
+ return (react_1.default.createElement(NavigationTabWrapper, { "data-component-name": "NavigationTabs/NavigationTab", className: className },
35
+ react_1.default.createElement(NavigationTabLink, { as: Link_1.Link, to: linkItem === null || linkItem === void 0 ? void 0 : linkItem.link, $active: active, external: linkItem === null || linkItem === void 0 ? void 0 : linkItem.external, target: linkItem === null || linkItem === void 0 ? void 0 : linkItem.target, "aria-current": active ? 'page' : undefined, onClick: () => telemetry.sendNavbarMenuItemClickedMessage((0, utils_1.getNavbarItemClickedPayload)(tab.type)) }, content)));
36
+ }
37
+ const NavigationTabChevron = (0, styled_components_1.default)(ChevronDownIcon_1.ChevronDownIcon) `
38
+ flex-shrink: 0;
39
+ `;
40
+ const NavigationTabWrapper = styled_components_1.default.li `
41
+ list-style: none;
42
+ display: inline-flex;
43
+ align-items: stretch;
44
+ flex-shrink: 0;
45
+ `;
46
+ const NavigationTabDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
47
+ display: inline-flex;
48
+ align-items: stretch;
49
+ height: 100%;
50
+ `;
51
+ const NavigationTabLink = styled_components_1.default.div `
52
+ display: inline-flex;
53
+ align-items: center;
54
+ gap: var(--navigation-tabs-item-content-gap);
55
+ box-sizing: border-box;
56
+ height: 100%;
57
+ padding: var(--navigation-tabs-item-padding);
58
+ font-size: var(--navigation-tabs-item-font-size);
59
+ line-height: var(--navigation-tabs-item-line-height);
60
+ white-space: nowrap;
61
+ text-decoration: none;
62
+ transition: border-color var(--navigation-tabs-item-transition);
63
+
64
+ font-weight: ${({ $active }) => $active
65
+ ? 'var(--navigation-tabs-item-font-weight-active)'
66
+ : 'var(--navigation-tabs-item-font-weight)'};
67
+ color: ${({ $active }) => $active
68
+ ? 'var(--navigation-tabs-item-text-color-active)'
69
+ : 'var(--navigation-tabs-item-text-color)'};
70
+ border-bottom: ${({ $active }) => $active
71
+ ? 'var(--navigation-tabs-item-bottom-border-active)'
72
+ : 'var(--navigation-tabs-item-bottom-border)'};
73
+
74
+ &:hover {
75
+ color: var(--navigation-tabs-item-text-color-hover);
76
+ border-bottom: ${({ $active }) => !$active && 'var(--navigation-tabs-item-bottom-border-hover)'};
77
+ }
78
+
79
+ &:focus-visible {
80
+ outline: 1px solid var(--navigation-tabs-item-border-color-focused);
81
+ outline-offset: 2px;
82
+ border-radius: var(--navigation-tabs-item-border-radius);
83
+ }
84
+ `;
85
+ const NavigationTabTrigger = (0, styled_components_1.default)(NavigationTabLink).attrs({ as: 'button', type: 'button' }) `
86
+ background: none;
87
+ border-top: none;
88
+ border-left: none;
89
+ border-right: none;
90
+ font-family: inherit;
91
+ cursor: pointer;
92
+ `;
93
+ //# sourceMappingURL=NavigationTab.js.map
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { NavigationTabRowItem } from '../../core/types';
3
+ export type NavigationTabContentProps = {
4
+ item: NavigationTabRowItem;
5
+ className?: string;
6
+ };
7
+ export declare function NavigationTabContent({ item, className }: NavigationTabContentProps): JSX.Element;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NavigationTabContent = NavigationTabContent;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const hooks_1 = require("../../core/hooks");
10
+ const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
11
+ const LaunchIcon_1 = require("../../icons/LaunchIcon/LaunchIcon");
12
+ function NavigationTabContent({ item, className }) {
13
+ const { useTranslate } = (0, hooks_1.useThemeHooks)();
14
+ const { translate } = useTranslate();
15
+ const label = translate(item.labelTranslationKey, item.label);
16
+ return (react_1.default.createElement(NavigationTabContentWrapper, { "data-component-name": "NavigationTabs/NavigationTabContent", className: className },
17
+ (item.icon || item.srcSet) && react_1.default.createElement(NavigationTabIcon, { icon: item.icon, srcSet: item.srcSet }),
18
+ react_1.default.createElement(NavigationTabLabel, { "data-label": label, "data-translation-key": item.labelTranslationKey }, label),
19
+ 'external' in item && item.external ? react_1.default.createElement(NavigationTabExternalIcon, { size: "10px" }) : null));
20
+ }
21
+ const NavigationTabContentWrapper = styled_components_1.default.span `
22
+ display: inline-flex;
23
+ align-items: center;
24
+ gap: var(--navigation-tabs-item-content-gap);
25
+ `;
26
+ const NavigationTabIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
27
+ --icon-width: var(--navigation-tabs-item-icon-size);
28
+ --icon-height: var(--navigation-tabs-item-icon-size);
29
+ flex-shrink: 0;
30
+ `;
31
+ const NavigationTabLabel = styled_components_1.default.span `
32
+ display: inline-flex;
33
+ flex-direction: column;
34
+ cursor: pointer;
35
+ vertical-align: middle;
36
+
37
+ &::after {
38
+ content: attr(data-label);
39
+ height: 0;
40
+ overflow: hidden;
41
+ visibility: hidden;
42
+ pointer-events: none;
43
+ font-weight: var(--navigation-tabs-item-label-font-weight-active);
44
+ }
45
+ `;
46
+ const NavigationTabExternalIcon = (0, styled_components_1.default)(LaunchIcon_1.LaunchIcon) `
47
+ margin-left: var(--navigation-tabs-item-external-icon-margin-left);
48
+ flex-shrink: 0;
49
+ `;
50
+ //# sourceMappingURL=NavigationTabContent.js.map
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { NavigationTabItem } from '../../core/types';
3
+ export type NavigationTabMenuProps = {
4
+ items: NavigationTabItem[];
5
+ className?: string;
6
+ };
7
+ export declare function NavigationTabMenu({ items, className }: NavigationTabMenuProps): JSX.Element;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NavigationTabMenu = NavigationTabMenu;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
10
+ const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
11
+ const NavigationTabContent_1 = require("../../components/NavigationTabs/NavigationTabContent");
12
+ function NavigationTabMenu({ items, className }) {
13
+ return (react_1.default.createElement(NavigationTabMenuWrapper, { "data-component-name": "NavigationTabs/NavigationTabMenu", className: className },
14
+ react_1.default.createElement(DropdownMenu_1.DropdownMenu, null, items.map((item, index) => (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { key: `${item.label}_${index}`, to: item.link, external: item.external, "data-translation-key": item.labelTranslationKey, active: item.active, "aria-current": item.active ? 'page' : undefined },
15
+ react_1.default.createElement(NavigationTabContent_1.NavigationTabContent, { item: item })))))));
16
+ }
17
+ const NavigationTabMenuWrapper = styled_components_1.default.div ``;
18
+ //# sourceMappingURL=NavigationTabMenu.js.map
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { NavigationTabsConfig } from '../../core/types';
3
+ export type NavigationTabsProps = {
4
+ config?: NavigationTabsConfig;
5
+ className?: string;
6
+ };
7
+ export declare function NavigationTabs({ config, className }: NavigationTabsProps): JSX.Element | null;