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

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 (123) hide show
  1. package/lib/components/Catalog/Catalog.js +1 -1
  2. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.d.ts +1 -1
  3. package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
  4. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
  5. package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +30 -11
  6. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
  7. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
  8. package/lib/components/Dropdown/Dropdown.js +3 -1
  9. package/lib/components/Dropdown/DropdownMenu.d.ts +1 -0
  10. package/lib/components/Dropdown/DropdownMenu.js +1 -1
  11. package/lib/components/Feedback/Reasons.js +3 -2
  12. package/lib/components/Filter/FilterCheckboxes.js +30 -11
  13. package/lib/components/Image/Image.js +24 -4
  14. package/lib/components/Markdown/Markdown.js +3 -2
  15. package/lib/components/Menu/Menu.js +4 -0
  16. package/lib/components/Menu/MenuSelect.d.ts +7 -0
  17. package/lib/components/Menu/MenuSelect.js +129 -0
  18. package/lib/components/Menu/variables.js +43 -4
  19. package/lib/components/Navbar/Navbar.js +44 -5
  20. package/lib/components/Navbar/variables.js +3 -0
  21. package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
  22. package/lib/components/NavigationTabs/NavigationTab.js +93 -0
  23. package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
  24. package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
  25. package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
  26. package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
  27. package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
  28. package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
  29. package/lib/components/NavigationTabs/variables.d.ts +1 -0
  30. package/lib/components/NavigationTabs/variables.js +37 -0
  31. package/lib/components/Search/SearchTrigger.js +8 -2
  32. package/lib/components/Segmented/Segmented.js +23 -3
  33. package/lib/components/Select/Select.js +10 -3
  34. package/lib/components/Select/SelectInput.d.ts +1 -0
  35. package/lib/components/Select/SelectInput.js +3 -3
  36. package/lib/components/Sidebar/Sidebar.js +2 -2
  37. package/lib/components/TableOfContent/TableOfContent.js +2 -2
  38. package/lib/core/constants/common.d.ts +1 -0
  39. package/lib/core/constants/common.js +1 -0
  40. package/lib/core/hooks/index.d.ts +2 -0
  41. package/lib/core/hooks/index.js +2 -0
  42. package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
  43. package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
  44. package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
  45. package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
  46. package/lib/core/hooks/use-tab-list.d.ts +31 -0
  47. package/lib/core/hooks/use-tab-list.js +49 -0
  48. package/lib/core/hooks/use-theme-hooks.js +2 -0
  49. package/lib/core/styles/global.js +12 -2
  50. package/lib/core/types/hooks.d.ts +5 -0
  51. package/lib/core/types/index.d.ts +1 -0
  52. package/lib/core/types/l10n.d.ts +1 -1
  53. package/lib/core/types/navigation-tabs.d.ts +49 -0
  54. package/lib/core/types/navigation-tabs.js +3 -0
  55. package/lib/core/utils/Dynamic.d.ts +8 -1
  56. package/lib/core/utils/Dynamic.js +34 -3
  57. package/lib/core/utils/index.d.ts +1 -0
  58. package/lib/core/utils/index.js +1 -0
  59. package/lib/core/utils/menu.d.ts +4 -0
  60. package/lib/core/utils/menu.js +42 -3
  61. package/lib/core/utils/navigation-tabs.d.ts +8 -0
  62. package/lib/core/utils/navigation-tabs.js +71 -0
  63. package/lib/index.d.ts +5 -0
  64. package/lib/index.js +7 -1
  65. package/lib/layouts/PageLayout.js +1 -1
  66. package/lib/layouts/RootLayout.js +2 -2
  67. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
  68. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
  69. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
  70. package/package.json +3 -3
  71. package/src/components/Catalog/Catalog.tsx +1 -1
  72. package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
  73. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
  74. package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +37 -22
  75. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
  76. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
  77. package/src/components/Dropdown/Dropdown.tsx +4 -1
  78. package/src/components/Dropdown/DropdownMenu.tsx +7 -1
  79. package/src/components/Feedback/Reasons.tsx +3 -2
  80. package/src/components/Filter/FilterCheckboxes.tsx +33 -18
  81. package/src/components/Image/Image.tsx +26 -5
  82. package/src/components/Markdown/Markdown.tsx +3 -2
  83. package/src/components/Menu/Menu.tsx +5 -0
  84. package/src/components/Menu/MenuSelect.tsx +198 -0
  85. package/src/components/Menu/variables.ts +43 -4
  86. package/src/components/Navbar/Navbar.tsx +22 -5
  87. package/src/components/Navbar/variables.ts +3 -0
  88. package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
  89. package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
  90. package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
  91. package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
  92. package/src/components/NavigationTabs/variables.ts +34 -0
  93. package/src/components/Search/SearchTrigger.tsx +11 -2
  94. package/src/components/Segmented/Segmented.tsx +25 -16
  95. package/src/components/Select/Select.tsx +12 -6
  96. package/src/components/Select/SelectInput.tsx +8 -10
  97. package/src/components/Sidebar/Sidebar.tsx +2 -2
  98. package/src/components/TableOfContent/TableOfContent.tsx +2 -2
  99. package/src/core/constants/common.ts +1 -0
  100. package/src/core/hooks/__mocks__/use-theme-hooks.ts +3 -0
  101. package/src/core/hooks/index.ts +2 -0
  102. package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
  103. package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
  104. package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
  105. package/src/core/hooks/use-tab-list.ts +63 -0
  106. package/src/core/hooks/use-theme-hooks.ts +2 -0
  107. package/src/core/styles/global.ts +12 -2
  108. package/src/core/types/hooks.ts +5 -0
  109. package/src/core/types/index.ts +1 -0
  110. package/src/core/types/l10n.ts +3 -0
  111. package/src/core/types/navigation-tabs.ts +54 -0
  112. package/src/core/utils/Dynamic.tsx +67 -35
  113. package/src/core/utils/index.ts +1 -0
  114. package/src/core/utils/menu.ts +49 -3
  115. package/src/core/utils/navigation-tabs.ts +99 -0
  116. package/src/icons/CheckboxIcon/CheckboxIcon.tsx +1 -0
  117. package/src/icons/ChevronSortIcon/ChevronSortIcon.tsx +1 -0
  118. package/src/index.ts +6 -0
  119. package/src/layouts/PageLayout.tsx +1 -1
  120. package/src/layouts/RootLayout.tsx +2 -2
  121. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
  122. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +3 -3
  123. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -1
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -6,7 +15,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
15
  exports.dynamic = dynamic;
7
16
  const react_1 = __importDefault(require("react"));
8
17
  function dynamic(factory, { ssr = true, loading } = {}) {
9
- const Component = react_1.default.lazy(() => factory().then((mod) => {
18
+ let loaded;
19
+ let pending;
20
+ const load = () => (pending !== null && pending !== void 0 ? pending : (pending = factory()
21
+ .then((mod) => {
10
22
  // Case 1: factory() => import('./SomeModule') - direct import
11
23
  // Case 2: factory() => import('./SomeModule').then(mod => mod.default) - extract default
12
24
  if (typeof mod === 'function') {
@@ -38,10 +50,21 @@ function dynamic(factory, { ssr = true, loading } = {}) {
38
50
  }
39
51
  }
40
52
  throw new Error('Dynamic import did not return a valid React component');
41
- }));
53
+ })
54
+ .then((module) => {
55
+ loaded = module.default;
56
+ return module;
57
+ }, (error) => {
58
+ // A failed load is not kept, so the next preload tries again.
59
+ pending = undefined;
60
+ throw error;
61
+ })));
62
+ const LazyComponent = react_1.default.lazy(load);
42
63
  const LoadingComponent = loading || (() => null);
43
- return (props) => {
64
+ const DynamicComponent = (props) => {
44
65
  const [hasMounted, setHasMounted] = react_1.default.useState(false);
66
+ // Fixed per instance: a change of the element type would remount the component.
67
+ const [Component] = react_1.default.useState(() => loaded !== null && loaded !== void 0 ? loaded : LazyComponent);
45
68
  react_1.default.useEffect(() => {
46
69
  setHasMounted(true);
47
70
  }, []);
@@ -55,5 +78,13 @@ function dynamic(factory, { ssr = true, loading } = {}) {
55
78
  return (react_1.default.createElement(react_1.default.Suspense, { fallback: react_1.default.createElement(LoadingComponent, Object.assign({}, props)) },
56
79
  react_1.default.createElement(Component, Object.assign({}, props))));
57
80
  };
81
+ return Object.assign(DynamicComponent, {
82
+ preload() {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ if (ssr || typeof window !== 'undefined')
85
+ yield load();
86
+ });
87
+ },
88
+ });
58
89
  }
59
90
  //# sourceMappingURL=Dynamic.js.map
@@ -17,6 +17,7 @@ export * from './type-guards';
17
17
  export * from './dom';
18
18
  export * from './toc';
19
19
  export * from './menu';
20
+ export * from './navigation-tabs';
20
21
  export * from './load-and-navigate';
21
22
  export * from './get-scorecard-color-variable';
22
23
  export * from './change-text-casing';
@@ -33,6 +33,7 @@ __exportStar(require("./type-guards"), exports);
33
33
  __exportStar(require("./dom"), exports);
34
34
  __exportStar(require("./toc"), exports);
35
35
  __exportStar(require("./menu"), exports);
36
+ __exportStar(require("./navigation-tabs"), exports);
36
37
  __exportStar(require("./load-and-navigate"), exports);
37
38
  __exportStar(require("./get-scorecard-color-variable"), exports);
38
39
  __exportStar(require("./change-text-casing"), exports);
@@ -2,9 +2,13 @@ import type { ResolvedNavItem, Version } from '@redocly/config';
2
2
  import type { Location } from 'react-router';
3
3
  import type { Locale, TFunction } from '../types/l10n';
4
4
  import type { ItemState } from '../types/sidebar';
5
+ import type { NavigationTabsState } from '../types/navigation-tabs';
5
6
  import { MenuItemType } from '../constants/common';
6
7
  export declare const mapNavbarItems: (items: ResolvedNavItem[], defaultLocale: string, currentLocale: string, locales: Locale[], location: Location) => ItemState[];
7
8
  export declare const isItemActive: (item: ResolvedNavItem, defaultLocale: string, currentLocale: string, locales: Locale[], location: Location) => boolean;
8
9
  export declare const buildLanguagesGroup: (locales: Locale[], defaultLocale: string, currentLocale: string) => ResolvedNavItem | undefined;
9
10
  export declare const buildVersionSection: (translate: TFunction, versions: Version[], activeVersion?: Version) => ResolvedNavItem[];
11
+ export declare const buildNavigationTabsSelect: ({ navigationTabs, }: {
12
+ navigationTabs: NavigationTabsState | undefined;
13
+ }) => ItemState | undefined;
10
14
  export declare function getMenuItemType(item: ItemState): MenuItemType;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildVersionSection = exports.buildLanguagesGroup = exports.isItemActive = exports.mapNavbarItems = void 0;
3
+ exports.buildNavigationTabsSelect = exports.buildVersionSection = exports.buildLanguagesGroup = exports.isItemActive = exports.mapNavbarItems = void 0;
4
4
  exports.getMenuItemType = getMenuItemType;
5
5
  const common_1 = require("../constants/common");
6
6
  const urls_1 = require("./urls");
7
+ const navigation_tabs_1 = require("./navigation-tabs");
7
8
  const TRANSLATION_KEYS = {
8
9
  version: 'mobileMenu.version',
9
10
  };
@@ -35,7 +36,7 @@ const buildLanguagesGroup = (locales, defaultLocale, currentLocale) => {
35
36
  .filter((locale) => locale.code !== currentLocale)
36
37
  .map((locale) => {
37
38
  const newLangPathname = (0, urls_1.getPathnameForLocale)((0, urls_1.withoutPathPrefix)(location.pathname), defaultLocale, locale.code, locales);
38
- const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
39
+ const newUrlWithLanguage = `${(0, urls_1.addLeadingSlash)(newLangPathname)}${location.search}${location.hash}`;
39
40
  return {
40
41
  type: 'link',
41
42
  label: locale.name || locale.code || '',
@@ -72,9 +73,30 @@ const buildVersionSection = (translate, versions, activeVersion) => {
72
73
  ];
73
74
  };
74
75
  exports.buildVersionSection = buildVersionSection;
76
+ const buildNavigationTabsSelect = ({ navigationTabs, }) => {
77
+ var _a;
78
+ var _b;
79
+ const tabs = (_a = (0, navigation_tabs_1.toNavigationTabsConfig)({ state: navigationTabs })) === null || _a === void 0 ? void 0 : _a.items;
80
+ if (!tabs) {
81
+ return;
82
+ }
83
+ const activeTab = tabs.find((tab) => tab.active);
84
+ return {
85
+ type: common_1.MenuItemType.Select,
86
+ label: (_b = activeTab === null || activeTab === void 0 ? void 0 : activeTab.label) !== null && _b !== void 0 ? _b : 'Navigation tabs',
87
+ labelTranslationKey: activeTab ? activeTab.labelTranslationKey : 'navigationTabs.label',
88
+ items: tabs.map(toNavigationTabOption),
89
+ active: false,
90
+ hasActiveSubItem: !!activeTab,
91
+ };
92
+ };
93
+ exports.buildNavigationTabsSelect = buildNavigationTabsSelect;
75
94
  function getMenuItemType(item) {
76
95
  var _a, _b;
77
- if (item.type === common_1.MenuItemType.Separator) {
96
+ if (item.type === common_1.MenuItemType.Select) {
97
+ return common_1.MenuItemType.Select;
98
+ }
99
+ else if (item.type === common_1.MenuItemType.Separator) {
78
100
  return common_1.MenuItemType.Separator;
79
101
  }
80
102
  else if (item.menuStyle === 'drilldown') {
@@ -89,4 +111,21 @@ function getMenuItemType(item) {
89
111
  else
90
112
  return common_1.MenuItemType.Default;
91
113
  }
114
+ function toNavigationTabOption(tab) {
115
+ var _a;
116
+ const landing = tab.type === 'group' ? ((_a = tab.items.find((entry) => entry.active)) !== null && _a !== void 0 ? _a : tab.items[0]) : tab;
117
+ return {
118
+ type: tab.type,
119
+ label: tab.label,
120
+ labelTranslationKey: tab.labelTranslationKey,
121
+ icon: tab.icon,
122
+ srcSet: tab.srcSet,
123
+ link: landing === null || landing === void 0 ? void 0 : landing.link,
124
+ external: landing === null || landing === void 0 ? void 0 : landing.external,
125
+ target: landing === null || landing === void 0 ? void 0 : landing.target,
126
+ items: [],
127
+ active: !!tab.active,
128
+ hasActiveSubItem: false,
129
+ };
130
+ }
92
131
  //# sourceMappingURL=menu.js.map
@@ -0,0 +1,8 @@
1
+ import type { ThemeHooks } from '../types/hooks';
2
+ import type { NavigationTabsConfig, NavigationTabsState } from '../types/navigation-tabs';
3
+ type NavbarItemClickedPayload = Parameters<ReturnType<ThemeHooks['useTelemetry']>['sendNavbarMenuItemClickedMessage']>[0];
4
+ export declare function toNavigationTabsConfig({ state, }: {
5
+ state: NavigationTabsState | undefined;
6
+ }): NavigationTabsConfig | undefined;
7
+ export declare function getNavbarItemClickedPayload(type: 'link' | 'group'): NavbarItemClickedPayload;
8
+ export {};
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.toNavigationTabsConfig = toNavigationTabsConfig;
15
+ exports.getNavbarItemClickedPayload = getNavbarItemClickedPayload;
16
+ const get_base_data_attributes_1 = require("./telemetry/get-base-data-attributes");
17
+ function toNavigationTabsConfig({ state, }) {
18
+ const items = toNavigationTabEntries(state).map((entry) => entry.kind === 'menu'
19
+ ? {
20
+ type: 'group',
21
+ label: entry.tab.label,
22
+ labelTranslationKey: entry.tab.labelTranslationKey,
23
+ icon: entry.tab.icon,
24
+ srcSet: entry.tab.srcSet,
25
+ items: entry.entries.map((_a) => {
26
+ var { active } = _a, link = __rest(_a, ["active"]);
27
+ return toRowLink(link, active);
28
+ }),
29
+ active: entry.active,
30
+ }
31
+ : toRowLink(entry.link, entry.active));
32
+ return items.length ? { items } : undefined;
33
+ }
34
+ function getNavbarItemClickedPayload(type) {
35
+ return [
36
+ Object.assign(Object.assign({}, (0, get_base_data_attributes_1.getBaseDataAttributes)('navbarItem', 'navbar')), { type }),
37
+ ];
38
+ }
39
+ function toNavigationTabEntries(state) {
40
+ if (!(state === null || state === void 0 ? void 0 : state.tabs.length))
41
+ return [];
42
+ return state.tabs.flatMap((tab) => {
43
+ var _a;
44
+ const active = ((_a = state.activeTab) === null || _a === void 0 ? void 0 : _a.tabId) === tab.tabId;
45
+ if (tab.menu) {
46
+ const entries = tab.menu
47
+ .filter((menuEntry) => !!menuEntry.link)
48
+ .map((_a) => { var _b; var { tabId } = _a, link = __rest(_a, ["tabId"]); return (Object.assign(Object.assign({}, link), { active: active && tabId === ((_b = state.activeMenuEntry) === null || _b === void 0 ? void 0 : _b.tabId) })); });
49
+ return entries.length ? [{ kind: 'menu', tab, entries, active }] : [];
50
+ }
51
+ if (!tab.link)
52
+ return [];
53
+ return [
54
+ {
55
+ kind: 'link',
56
+ link: {
57
+ label: tab.label,
58
+ labelTranslationKey: tab.labelTranslationKey,
59
+ link: tab.link,
60
+ icon: tab.icon,
61
+ srcSet: tab.srcSet,
62
+ },
63
+ active,
64
+ },
65
+ ];
66
+ });
67
+ }
68
+ function toRowLink(link, active) {
69
+ return Object.assign(Object.assign({ type: 'link' }, link), { active });
70
+ }
71
+ //# sourceMappingURL=navigation-tabs.js.map
package/lib/index.d.ts CHANGED
@@ -46,6 +46,11 @@ export * from './components/Navbar/Navbar';
46
46
  export * from './components/Navbar/NavbarItem';
47
47
  export * from './components/Navbar/NavbarLogo';
48
48
  export * from './components/Navbar/NavbarMenu';
49
+ export * from './components/NavigationTabs/NavigationTabs';
50
+ export { NavigationTab } from './components/NavigationTabs/NavigationTab';
51
+ export type { NavigationTabProps } from './components/NavigationTabs/NavigationTab';
52
+ export * from './components/NavigationTabs/NavigationTabMenu';
53
+ export * from './components/NavigationTabs/NavigationTabContent';
49
54
  export * from './components/Footer/Footer';
50
55
  export * from './components/Footer/FooterColumn';
51
56
  export * from './components/Footer/FooterCopyright';
package/lib/index.js CHANGED
@@ -36,7 +36,7 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.markdoc = void 0;
39
+ exports.markdoc = exports.NavigationTab = void 0;
40
40
  __exportStar(require("./core"), exports);
41
41
  __exportStar(require("./ext/configure"), exports);
42
42
  /* Components */
@@ -90,6 +90,12 @@ __exportStar(require("./components/Navbar/Navbar"), exports);
90
90
  __exportStar(require("./components/Navbar/NavbarItem"), exports);
91
91
  __exportStar(require("./components/Navbar/NavbarLogo"), exports);
92
92
  __exportStar(require("./components/Navbar/NavbarMenu"), exports);
93
+ /* NavigationTabs */
94
+ __exportStar(require("./components/NavigationTabs/NavigationTabs"), exports);
95
+ var NavigationTab_1 = require("./components/NavigationTabs/NavigationTab");
96
+ Object.defineProperty(exports, "NavigationTab", { enumerable: true, get: function () { return NavigationTab_1.NavigationTab; } });
97
+ __exportStar(require("./components/NavigationTabs/NavigationTabMenu"), exports);
98
+ __exportStar(require("./components/NavigationTabs/NavigationTabContent"), exports);
93
99
  /* Footer */
94
100
  __exportStar(require("./components/Footer/Footer"), exports);
95
101
  __exportStar(require("./components/Footer/FooterColumn"), exports);
@@ -16,7 +16,7 @@ function PageLayout({ sidebar, children, }) {
16
16
  const Container = styled_components_1.default.div `
17
17
  display: flex;
18
18
  flex-direction: row;
19
- min-height: calc(100vh - var(--navbar-height) - var(--banner-height));
19
+ min-height: calc(100vh - var(--navbar-offset));
20
20
 
21
21
  @media screen and (min-width: ${utils_1.breakpoints.max}) {
22
22
  max-width: var(--container-max-width);
@@ -11,8 +11,8 @@ const SkipContent_1 = require("../components/SkipContent/SkipContent");
11
11
  const AIAssistantButton_1 = require("../components/Buttons/AIAssistantButton");
12
12
  const hooks_1 = require("../core/hooks");
13
13
  function RootLayout({ children }) {
14
- const { useSearch } = (0, hooks_1.useThemeHooks)();
15
- const { askAi } = useSearch();
14
+ const { useSearchFeatures } = (0, hooks_1.useThemeHooks)();
15
+ const { askAi } = useSearchFeatures();
16
16
  return (react_1.default.createElement("div", { "data-component-name": "layouts/RootLayout" },
17
17
  react_1.default.createElement(SkipContent_1.SkipContent, null),
18
18
  react_1.default.createElement(Navbar_1.Navbar, null),
@@ -41,7 +41,7 @@ const FilterWrapper = styled_components_1.default.div `
41
41
  padding-right: var(--spacing-xl);
42
42
  padding-left: var(--spacing-xl);
43
43
  padding-bottom: var(--spacing-xs);
44
- top: var(--navbar-height);
44
+ top: var(--navbar-stack-height);
45
45
  background-color: var(--bg-color);
46
46
  z-index: var(--z-index-raised);
47
47
  max-width: var(--md-content-max-width);
@@ -68,9 +68,9 @@ const CodePanelWrapper = styled_components_1.default.div `
68
68
  border: 1px solid var(--code-panel-border-color);
69
69
  border-radius: var(--code-panel-border-radius);
70
70
  overflow: clip;
71
- --code-block-max-height: calc(100vh - var(--navbar-height) - 2 * var(--spacing-xl));
72
- height: calc(100vh - var(--navbar-height) - 2 * var(--spacing-xl));
71
+ --code-block-max-height: calc(100vh - var(--navbar-stack-height) - 2 * var(--spacing-xl));
72
+ height: calc(100vh - var(--navbar-stack-height) - 2 * var(--spacing-xl));
73
73
  position: sticky;
74
- top: calc(var(--navbar-height) + var(--spacing-xl));
74
+ top: calc(var(--navbar-stack-height) + var(--spacing-xl));
75
75
  `;
76
76
  //# sourceMappingURL=CodePanel.js.map
@@ -95,7 +95,7 @@ const DocsPanel = styled_components_1.default.div `
95
95
  flex-direction: column;
96
96
 
97
97
  min-height: 0;
98
- min-height: calc(100vh - var(--navbar-height));
98
+ min-height: calc(100vh - var(--navbar-stack-height));
99
99
 
100
100
  padding-top: var(--spacing-xl);
101
101
  padding-right: var(--spacing-xs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.70.0-next.3",
3
+ "version": "0.70.0-next.5",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -42,7 +42,7 @@
42
42
  "devDependencies": {
43
43
  "@babel/core": "7.29.7",
44
44
  "@markdoc/markdoc": "0.5.2",
45
- "@redocly/realm-asyncapi-sdk": "0.16.0-next.1",
45
+ "@redocly/realm-asyncapi-sdk": "0.16.0-next.2",
46
46
  "@shikijs/types": "3.21.0",
47
47
  "@testing-library/react": "16.3.0",
48
48
  "@testing-library/user-event": "14.6.1",
@@ -71,7 +71,7 @@
71
71
  "webpack": "5.105.2"
72
72
  },
73
73
  "dependencies": {
74
- "@redocly/config": "0.58.0",
74
+ "@redocly/config": "0.61.1",
75
75
  "@tanstack/react-query": "5.62.3",
76
76
  "@tanstack/react-virtual": "3.13.0",
77
77
  "@xyflow/react": "12.8.3",
@@ -256,7 +256,7 @@ const CatalogDescription = styled.p`
256
256
  const CatalogPageWrapper = styled.div`
257
257
  --sidebar-width: var(--catalog-sidebar-width);
258
258
 
259
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
259
+ height: calc(100vh - var(--navbar-offset));
260
260
  display: flex;
261
261
  flex-direction: column;
262
262
  overflow: hidden;
@@ -164,10 +164,10 @@ export function CatalogEntityHistorySidebar({
164
164
 
165
165
  const SidebarOverlay = styled.div`
166
166
  position: fixed;
167
- top: calc(var(--navbar-height) + var(--banner-height));
167
+ top: var(--navbar-offset);
168
168
  left: 0;
169
169
  width: var(--sidebar-width);
170
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
170
+ height: calc(100vh - var(--navbar-offset));
171
171
  padding: var(--catalog-history-sidebar-padding);
172
172
  background-color: var(--catalog-history-sidebar-bg-color);
173
173
  border-right: 1px solid var(--catalog-history-sidebar-border-color);
@@ -120,7 +120,7 @@ const SplitViewWrapper = styled.div`
120
120
  const SchemaSampleWrapper = styled.div`
121
121
  flex: 1;
122
122
  position: sticky;
123
- top: calc(var(--navbar-height) + var(--banner-height) + var(--spacing-md));
123
+ top: calc(var(--navbar-offset) + var(--spacing-md));
124
124
  align-self: flex-start;
125
125
  padding-top: var(--spacing-sm);
126
126
  `;
@@ -96,30 +96,28 @@ export function CatalogFilterCheckboxes({
96
96
  <FilterOptions>
97
97
  {filteredOptions.map(({ value, count }) => {
98
98
  const id = 'filter--' + filter.property + '--' + value;
99
+ const checked =
100
+ filter.selectedOptions instanceof Set
101
+ ? filter.selectedOptions.has(value) ||
102
+ filter.selectedOptions.has(value?.toLowerCase())
103
+ : false;
99
104
  return (
100
- <FilterCheckboxOption
101
- key={id}
102
- role="link"
103
- onClick={() => {
104
- filter.toggleOption(value);
105
- telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
106
- {
107
- ...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
108
- category: filter.property,
109
- value: value,
110
- },
111
- ]);
112
- }}
113
- >
114
- <CheckboxIcon
115
- checked={
116
- filter.selectedOptions instanceof Set
117
- ? filter.selectedOptions.has(value) ||
118
- filter.selectedOptions.has(value?.toLowerCase())
119
- : false
120
- }
121
- />
105
+ <FilterCheckboxOption key={id}>
106
+ <CheckboxIcon checked={checked} />
122
107
  <FilterOptionLabel data-translation-key={value}>
108
+ <FilterCheckboxInput
109
+ checked={checked}
110
+ onChange={() => {
111
+ filter.toggleOption(value);
112
+ telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
113
+ {
114
+ ...getBaseDataAttributes('catalogEntitiesFilterCheckboxId', 'checkbox'),
115
+ category: filter.property,
116
+ value: value,
117
+ },
118
+ ]);
119
+ }}
120
+ />
123
121
  {highlightText(changeTextCasing(translate(value), filterValuesCasing) || '')}
124
122
  </FilterOptionLabel>
125
123
  {showCounter && <CounterTag borderless>{count}</CounterTag>}
@@ -168,6 +166,23 @@ const HighlightedText = styled.span`
168
166
 
169
167
  const FilterCheckboxOption = styled(FilterOption)`
170
168
  padding-left: var(--filter-option-checkbox-padding-left);
169
+
170
+ &:has(input:focus-visible) {
171
+ outline: 1px solid var(--button-border-color-focused);
172
+ outline-offset: -1px;
173
+ }
174
+ `;
175
+
176
+ const FilterCheckboxInput = styled.input.attrs({ type: 'checkbox' })`
177
+ position: absolute;
178
+ width: 1px;
179
+ height: 1px;
180
+ margin: -1px;
181
+ padding: 0;
182
+ overflow: hidden;
183
+ clip: rect(0 0 0 0);
184
+ white-space: nowrap;
185
+ border: 0;
171
186
  `;
172
187
 
173
188
  const FilterSearchWrapper = styled.div`
@@ -23,7 +23,7 @@ export function CatalogMobileFiltersPanel({
23
23
 
24
24
  const CatalogMobileFiltersPanelWrapper = styled.div`
25
25
  width: 100%;
26
- max-height: calc(100vh - var(--navbar-height) - var(--banner-height));
26
+ max-height: calc(100vh - var(--navbar-offset));
27
27
  overflow-y: auto;
28
28
  background: var(--sidebar-bg-color);
29
29
  display: flex;
@@ -27,10 +27,10 @@ export function CatalogMobileFiltersPanelOverlay({
27
27
  const CatalogMobileFiltersPanelOverlayWrapper = styled.div`
28
28
  display: none;
29
29
  position: fixed;
30
- top: calc(var(--navbar-height) + var(--banner-height));
30
+ top: var(--navbar-offset);
31
31
  left: 0;
32
32
  width: 100%;
33
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
33
+ height: calc(100vh - var(--navbar-offset));
34
34
  z-index: 3;
35
35
  background: var(--bg-color);
36
36
  flex-direction: column;
@@ -156,13 +156,16 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
156
156
 
157
157
  const triggerChild = React.Children.only(trigger) as ReactElement<TriggerProps>;
158
158
 
159
+ const isLinkTrigger = Boolean(triggerChild.props?.to || triggerChild.props?.href);
160
+
159
161
  const dropdownTrigger = cloneElement(triggerChild, {
160
162
  onClick: triggerEvent === 'click' ? handleToggle : undefined,
163
+ 'aria-haspopup': 'menu',
161
164
  'aria-expanded': isOpen,
162
165
  icon: withArrow ? isOpen ? <ChevronUpIcon /> : <ChevronDownIcon /> : undefined,
163
166
  ...(withArrow ? { iconPosition: 'right' } : {}),
164
167
  ...triggerChild.props,
165
- onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined,
168
+ onKeyDown: triggerEvent === 'click' || !isLinkTrigger ? handleKeyDown : undefined,
166
169
  });
167
170
 
168
171
  const menu = (
@@ -6,7 +6,12 @@ import type { DropdownMenuItemProps } from '@redocly/theme/components/Dropdown/D
6
6
 
7
7
  import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
8
8
 
9
- export type DropdownMenuProps = { className?: string; role?: string; footer?: React.ReactNode } & (
9
+ export type DropdownMenuProps = {
10
+ id?: string;
11
+ className?: string;
12
+ role?: string;
13
+ footer?: React.ReactNode;
14
+ } & (
10
15
  | {
11
16
  items: DropdownMenuItemProps[];
12
17
  }
@@ -32,6 +37,7 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
32
37
  <DropdownMenuWrapper
33
38
  data-component-name="Dropdown/DropdownMenu"
34
39
  data-testid="dropdown-menu"
40
+ id={props.id}
35
41
  className={props.className}
36
42
  role={props.role || 'menu'}
37
43
  >
@@ -18,6 +18,7 @@ export type ReasonsProps = {
18
18
  export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.Element | null {
19
19
  const { label, component = 'checkbox', items = [] } = settings;
20
20
  const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
21
+ const idPrefix = React.useId();
21
22
  const { useTranslate } = useThemeHooks();
22
23
  const { translate } = useTranslate();
23
24
 
@@ -51,6 +52,7 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
51
52
  {items.map((reason, idx) => (
52
53
  <OptionWrapper key={reason}>
53
54
  <input
55
+ id={`${idPrefix}-${idx}`}
54
56
  type={component}
55
57
  value={reason}
56
58
  checked={checkedState[idx]}
@@ -59,8 +61,7 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
59
61
  />
60
62
  <label
61
63
  data-translation-key={`feedback.settings.reasons.items.${idx + 1}`}
62
- id={reason}
63
- onClick={() => handleOptionChange(idx)}
64
+ htmlFor={`${idPrefix}-${idx}`}
64
65
  >
65
66
  {translate(`feedback.settings.reasons.items.${idx + 1}`, reason)}
66
67
  </label>
@@ -30,26 +30,24 @@ export function FilterCheckboxes({
30
30
  <FilterOptions>
31
31
  {(filter.filteredOptions || filter.options).map(({ value, count }) => {
32
32
  const id = 'filter--' + filter.property + '--' + value;
33
+ const checked =
34
+ filter.selectedOptions instanceof Set
35
+ ? filter.selectedOptions.has(value) ||
36
+ filter.selectedOptions.has(value?.toLowerCase())
37
+ : false;
33
38
  return (
34
- <FilterCheckboxOption
35
- key={id}
36
- role="link"
37
- onClick={() => {
38
- filter.toggleOption(value);
39
- telemetry.sendFilterCheckboxToggledMessage([
40
- getBaseDataAttributes('filterId', 'checkbox'),
41
- ]);
42
- }}
43
- >
44
- <CheckboxIcon
45
- checked={
46
- filter.selectedOptions instanceof Set
47
- ? filter.selectedOptions.has(value) ||
48
- filter.selectedOptions.has(value?.toLowerCase())
49
- : false
50
- }
51
- />
39
+ <FilterCheckboxOption key={id}>
40
+ <CheckboxIcon checked={checked} />
52
41
  <FilterOptionLabel data-translation-key={value}>
42
+ <FilterCheckboxInput
43
+ checked={checked}
44
+ onChange={() => {
45
+ filter.toggleOption(value);
46
+ telemetry.sendFilterCheckboxToggledMessage([
47
+ getBaseDataAttributes('filterId', 'checkbox'),
48
+ ]);
49
+ }}
50
+ />
53
51
  {changeTextCasing(translate(value), filterValuesCasing)}
54
52
  </FilterOptionLabel>
55
53
  {showCounter && <CounterTag borderless>{count}</CounterTag>}
@@ -63,6 +61,23 @@ export function FilterCheckboxes({
63
61
 
64
62
  const FilterCheckboxOption = styled(FilterOption)`
65
63
  padding-left: var(--filter-option-checkbox-padding-left);
64
+
65
+ &:has(input:focus-visible) {
66
+ outline: 1px solid var(--button-border-color-focused);
67
+ outline-offset: -1px;
68
+ }
69
+ `;
70
+
71
+ const FilterCheckboxInput = styled.input.attrs({ type: 'checkbox' })`
72
+ position: absolute;
73
+ width: 1px;
74
+ height: 1px;
75
+ margin: -1px;
76
+ padding: 0;
77
+ overflow: hidden;
78
+ clip: rect(0 0 0 0);
79
+ white-space: nowrap;
80
+ border: 0;
66
81
  `;
67
82
 
68
83
  const FilterCheckboxesWrapper = styled.div`