@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.
- package/lib/components/Catalog/Catalog.js +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
- package/lib/components/Dropdown/Dropdown.js +3 -1
- package/lib/components/Markdown/Markdown.js +3 -2
- package/lib/components/Menu/Menu.js +4 -0
- package/lib/components/Menu/MenuSelect.d.ts +7 -0
- package/lib/components/Menu/MenuSelect.js +129 -0
- package/lib/components/Menu/variables.js +43 -4
- package/lib/components/Navbar/Navbar.js +44 -5
- package/lib/components/Navbar/variables.js +3 -0
- package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTab.js +93 -0
- package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
- package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
- package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
- package/lib/components/NavigationTabs/variables.d.ts +1 -0
- package/lib/components/NavigationTabs/variables.js +37 -0
- package/lib/components/Search/SearchTrigger.js +8 -2
- package/lib/components/Sidebar/Sidebar.js +2 -2
- package/lib/components/TableOfContent/TableOfContent.js +2 -2
- package/lib/core/constants/common.d.ts +1 -0
- package/lib/core/constants/common.js +1 -0
- package/lib/core/hooks/index.d.ts +1 -0
- package/lib/core/hooks/index.js +1 -0
- package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
- package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
- package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
- package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
- package/lib/core/hooks/use-theme-hooks.js +2 -0
- package/lib/core/styles/global.js +12 -2
- package/lib/core/types/hooks.d.ts +5 -0
- package/lib/core/types/index.d.ts +1 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/navigation-tabs.d.ts +49 -0
- package/lib/core/types/navigation-tabs.js +3 -0
- package/lib/core/utils/index.d.ts +1 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/core/utils/menu.d.ts +4 -0
- package/lib/core/utils/menu.js +42 -3
- package/lib/core/utils/navigation-tabs.d.ts +8 -0
- package/lib/core/utils/navigation-tabs.js +71 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +7 -1
- package/lib/layouts/PageLayout.js +1 -1
- package/lib/layouts/RootLayout.js +2 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
- package/package.json +3 -3
- package/src/components/Catalog/Catalog.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
- package/src/components/Dropdown/Dropdown.tsx +4 -1
- package/src/components/Markdown/Markdown.tsx +3 -2
- package/src/components/Menu/Menu.tsx +5 -0
- package/src/components/Menu/MenuSelect.tsx +198 -0
- package/src/components/Menu/variables.ts +43 -4
- package/src/components/Navbar/Navbar.tsx +22 -5
- package/src/components/Navbar/variables.ts +3 -0
- package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
- package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
- package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
- package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
- package/src/components/NavigationTabs/variables.ts +34 -0
- package/src/components/Search/SearchTrigger.tsx +11 -2
- package/src/components/Sidebar/Sidebar.tsx +2 -2
- package/src/components/TableOfContent/TableOfContent.tsx +2 -2
- package/src/core/constants/common.ts +1 -0
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +2 -0
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
- package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
- package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
- package/src/core/hooks/use-theme-hooks.ts +2 -0
- package/src/core/styles/global.ts +12 -2
- package/src/core/types/hooks.ts +5 -0
- package/src/core/types/index.ts +1 -0
- package/src/core/types/l10n.ts +3 -0
- package/src/core/types/navigation-tabs.ts +54 -0
- package/src/core/utils/index.ts +1 -0
- package/src/core/utils/menu.ts +49 -3
- package/src/core/utils/navigation-tabs.ts +99 -0
- package/src/index.ts +6 -0
- package/src/layouts/PageLayout.tsx +1 -1
- package/src/layouts/RootLayout.tsx +2 -2
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +3 -3
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -1
package/src/core/utils/menu.ts
CHANGED
|
@@ -3,8 +3,10 @@ import type { Location } from 'react-router';
|
|
|
3
3
|
|
|
4
4
|
import type { Locale, TFunction } from '../types/l10n';
|
|
5
5
|
import type { ItemState } from '../types/sidebar';
|
|
6
|
+
import type { NavigationTabRowItem, NavigationTabsState } from '../types/navigation-tabs';
|
|
6
7
|
import { MenuItemType } from '../constants/common';
|
|
7
|
-
import { getPathnameForLocale, withoutPathPrefix, withPathPrefix } from './urls';
|
|
8
|
+
import { addLeadingSlash, getPathnameForLocale, withoutPathPrefix, withPathPrefix } from './urls';
|
|
9
|
+
import { toNavigationTabsConfig } from './navigation-tabs';
|
|
8
10
|
|
|
9
11
|
const TRANSLATION_KEYS = {
|
|
10
12
|
version: 'mobileMenu.version',
|
|
@@ -70,7 +72,7 @@ export const buildLanguagesGroup = (
|
|
|
70
72
|
locale.code,
|
|
71
73
|
locales,
|
|
72
74
|
);
|
|
73
|
-
const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
|
|
75
|
+
const newUrlWithLanguage = `${addLeadingSlash(newLangPathname)}${location.search}${location.hash}`;
|
|
74
76
|
return {
|
|
75
77
|
type: 'link',
|
|
76
78
|
label: locale.name || locale.code || '',
|
|
@@ -111,8 +113,33 @@ export const buildVersionSection = (
|
|
|
111
113
|
];
|
|
112
114
|
};
|
|
113
115
|
|
|
116
|
+
export const buildNavigationTabsSelect = ({
|
|
117
|
+
navigationTabs,
|
|
118
|
+
}: {
|
|
119
|
+
navigationTabs: NavigationTabsState | undefined;
|
|
120
|
+
}): ItemState | undefined => {
|
|
121
|
+
const tabs = toNavigationTabsConfig({ state: navigationTabs })?.items;
|
|
122
|
+
|
|
123
|
+
if (!tabs) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const activeTab = tabs.find((tab) => tab.active);
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
type: MenuItemType.Select,
|
|
131
|
+
label: activeTab?.label ?? 'Navigation tabs',
|
|
132
|
+
labelTranslationKey: activeTab ? activeTab.labelTranslationKey : 'navigationTabs.label',
|
|
133
|
+
items: tabs.map(toNavigationTabOption),
|
|
134
|
+
active: false,
|
|
135
|
+
hasActiveSubItem: !!activeTab,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
|
|
114
139
|
export function getMenuItemType(item: ItemState): MenuItemType {
|
|
115
|
-
if (item.type === MenuItemType.
|
|
140
|
+
if (item.type === MenuItemType.Select) {
|
|
141
|
+
return MenuItemType.Select;
|
|
142
|
+
} else if (item.type === MenuItemType.Separator) {
|
|
116
143
|
return MenuItemType.Separator;
|
|
117
144
|
} else if (item.menuStyle === 'drilldown') {
|
|
118
145
|
return MenuItemType.DrillDown;
|
|
@@ -122,3 +149,22 @@ export function getMenuItemType(item: ItemState): MenuItemType {
|
|
|
122
149
|
return MenuItemType.Operation;
|
|
123
150
|
} else return MenuItemType.Default;
|
|
124
151
|
}
|
|
152
|
+
|
|
153
|
+
function toNavigationTabOption(tab: NavigationTabRowItem): ItemState {
|
|
154
|
+
const landing =
|
|
155
|
+
tab.type === 'group' ? (tab.items.find((entry) => entry.active) ?? tab.items[0]) : tab;
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
type: tab.type,
|
|
159
|
+
label: tab.label,
|
|
160
|
+
labelTranslationKey: tab.labelTranslationKey,
|
|
161
|
+
icon: tab.icon,
|
|
162
|
+
srcSet: tab.srcSet,
|
|
163
|
+
link: landing?.link,
|
|
164
|
+
external: landing?.external,
|
|
165
|
+
target: landing?.target,
|
|
166
|
+
items: [],
|
|
167
|
+
active: !!tab.active,
|
|
168
|
+
hasActiveSubItem: false,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ThemeHooks } from '../types/hooks';
|
|
2
|
+
import type {
|
|
3
|
+
NavigationTab,
|
|
4
|
+
NavigationTabMenuEntry,
|
|
5
|
+
NavigationTabItem,
|
|
6
|
+
NavigationTabRowItem,
|
|
7
|
+
NavigationTabsConfig,
|
|
8
|
+
NavigationTabsState,
|
|
9
|
+
} from '../types/navigation-tabs';
|
|
10
|
+
|
|
11
|
+
import { getBaseDataAttributes } from './telemetry/get-base-data-attributes';
|
|
12
|
+
|
|
13
|
+
type NavbarItemClickedPayload = Parameters<
|
|
14
|
+
ReturnType<ThemeHooks['useTelemetry']>['sendNavbarMenuItemClickedMessage']
|
|
15
|
+
>[0];
|
|
16
|
+
|
|
17
|
+
export function toNavigationTabsConfig({
|
|
18
|
+
state,
|
|
19
|
+
}: {
|
|
20
|
+
state: NavigationTabsState | undefined;
|
|
21
|
+
}): NavigationTabsConfig | undefined {
|
|
22
|
+
const items = toNavigationTabEntries(state).map(
|
|
23
|
+
(entry): NavigationTabRowItem =>
|
|
24
|
+
entry.kind === 'menu'
|
|
25
|
+
? {
|
|
26
|
+
type: 'group',
|
|
27
|
+
label: entry.tab.label,
|
|
28
|
+
labelTranslationKey: entry.tab.labelTranslationKey,
|
|
29
|
+
icon: entry.tab.icon,
|
|
30
|
+
srcSet: entry.tab.srcSet,
|
|
31
|
+
items: entry.entries.map(({ active, ...link }) => toRowLink(link, active)),
|
|
32
|
+
active: entry.active,
|
|
33
|
+
}
|
|
34
|
+
: toRowLink(entry.link, entry.active),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
return items.length ? { items } : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getNavbarItemClickedPayload(type: 'link' | 'group'): NavbarItemClickedPayload {
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
...getBaseDataAttributes<'navbarItem', 'navbar', 'urn:redocly:realm:ui:navbar:navbarItem'>(
|
|
44
|
+
'navbarItem',
|
|
45
|
+
'navbar',
|
|
46
|
+
),
|
|
47
|
+
type,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type NavigationTabLink = Omit<NavigationTabMenuEntry, 'tabId'>;
|
|
53
|
+
|
|
54
|
+
type NavigationTabEntry =
|
|
55
|
+
| { kind: 'link'; link: NavigationTabLink; active: boolean }
|
|
56
|
+
| {
|
|
57
|
+
kind: 'menu';
|
|
58
|
+
tab: NavigationTab;
|
|
59
|
+
entries: Array<NavigationTabLink & { active: boolean }>;
|
|
60
|
+
active: boolean;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
function toNavigationTabEntries(state: NavigationTabsState | undefined): NavigationTabEntry[] {
|
|
64
|
+
if (!state?.tabs.length) return [];
|
|
65
|
+
|
|
66
|
+
return state.tabs.flatMap((tab): NavigationTabEntry[] => {
|
|
67
|
+
const active = state.activeTab?.tabId === tab.tabId;
|
|
68
|
+
|
|
69
|
+
if (tab.menu) {
|
|
70
|
+
const entries = tab.menu
|
|
71
|
+
.filter((menuEntry) => !!menuEntry.link)
|
|
72
|
+
.map(({ tabId, ...link }) => ({
|
|
73
|
+
...link,
|
|
74
|
+
active: active && tabId === state.activeMenuEntry?.tabId,
|
|
75
|
+
}));
|
|
76
|
+
return entries.length ? [{ kind: 'menu', tab, entries, active }] : [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!tab.link) return [];
|
|
80
|
+
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
kind: 'link',
|
|
84
|
+
link: {
|
|
85
|
+
label: tab.label,
|
|
86
|
+
labelTranslationKey: tab.labelTranslationKey,
|
|
87
|
+
link: tab.link,
|
|
88
|
+
icon: tab.icon,
|
|
89
|
+
srcSet: tab.srcSet,
|
|
90
|
+
},
|
|
91
|
+
active,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function toRowLink(link: NavigationTabLink, active: boolean): NavigationTabItem {
|
|
98
|
+
return { type: 'link', ...link, active };
|
|
99
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -53,6 +53,12 @@ export * from '@redocly/theme/components/Navbar/Navbar';
|
|
|
53
53
|
export * from '@redocly/theme/components/Navbar/NavbarItem';
|
|
54
54
|
export * from '@redocly/theme/components/Navbar/NavbarLogo';
|
|
55
55
|
export * from '@redocly/theme/components/Navbar/NavbarMenu';
|
|
56
|
+
/* NavigationTabs */
|
|
57
|
+
export * from '@redocly/theme/components/NavigationTabs/NavigationTabs';
|
|
58
|
+
export { NavigationTab } from '@redocly/theme/components/NavigationTabs/NavigationTab';
|
|
59
|
+
export type { NavigationTabProps } from '@redocly/theme/components/NavigationTabs/NavigationTab';
|
|
60
|
+
export * from '@redocly/theme/components/NavigationTabs/NavigationTabMenu';
|
|
61
|
+
export * from '@redocly/theme/components/NavigationTabs/NavigationTabContent';
|
|
56
62
|
/* Footer */
|
|
57
63
|
export * from '@redocly/theme/components/Footer/Footer';
|
|
58
64
|
export * from '@redocly/theme/components/Footer/FooterColumn';
|
|
@@ -27,7 +27,7 @@ export function PageLayout({
|
|
|
27
27
|
const Container = styled.div`
|
|
28
28
|
display: flex;
|
|
29
29
|
flex-direction: row;
|
|
30
|
-
min-height: calc(100vh - var(--navbar-
|
|
30
|
+
min-height: calc(100vh - var(--navbar-offset));
|
|
31
31
|
|
|
32
32
|
@media screen and (min-width: ${breakpoints.max}) {
|
|
33
33
|
max-width: var(--container-max-width);
|
|
@@ -13,8 +13,8 @@ export type LayoutConfig = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export function RootLayout({ children }: LayoutConfig): JSX.Element {
|
|
16
|
-
const {
|
|
17
|
-
const { askAi } =
|
|
16
|
+
const { useSearchFeatures } = useThemeHooks();
|
|
17
|
+
const { askAi } = useSearchFeatures();
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
20
|
<div data-component-name="layouts/RootLayout">
|
|
@@ -76,7 +76,7 @@ const FilterWrapper = styled.div`
|
|
|
76
76
|
padding-right: var(--spacing-xl);
|
|
77
77
|
padding-left: var(--spacing-xl);
|
|
78
78
|
padding-bottom: var(--spacing-xs);
|
|
79
|
-
top: var(--navbar-height);
|
|
79
|
+
top: var(--navbar-stack-height);
|
|
80
80
|
background-color: var(--bg-color);
|
|
81
81
|
z-index: var(--z-index-raised);
|
|
82
82
|
max-width: var(--md-content-max-width);
|
|
@@ -64,8 +64,8 @@ const CodePanelWrapper = styled.div`
|
|
|
64
64
|
border: 1px solid var(--code-panel-border-color);
|
|
65
65
|
border-radius: var(--code-panel-border-radius);
|
|
66
66
|
overflow: clip;
|
|
67
|
-
--code-block-max-height: calc(100vh - var(--navbar-height) - 2 * var(--spacing-xl));
|
|
68
|
-
height: calc(100vh - var(--navbar-height) - 2 * var(--spacing-xl));
|
|
67
|
+
--code-block-max-height: calc(100vh - var(--navbar-stack-height) - 2 * var(--spacing-xl));
|
|
68
|
+
height: calc(100vh - var(--navbar-stack-height) - 2 * var(--spacing-xl));
|
|
69
69
|
position: sticky;
|
|
70
|
-
top: calc(var(--navbar-height) + var(--spacing-xl));
|
|
70
|
+
top: calc(var(--navbar-stack-height) + var(--spacing-xl));
|
|
71
71
|
`;
|
|
@@ -78,7 +78,7 @@ const DocsPanel = styled.div`
|
|
|
78
78
|
flex-direction: column;
|
|
79
79
|
|
|
80
80
|
min-height: 0;
|
|
81
|
-
min-height: calc(100vh - var(--navbar-height));
|
|
81
|
+
min-height: calc(100vh - var(--navbar-stack-height));
|
|
82
82
|
|
|
83
83
|
padding-top: var(--spacing-xl);
|
|
84
84
|
padding-right: var(--spacing-xs);
|