@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
@@ -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.Separator) {
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
+ }
@@ -11,6 +11,7 @@ const Icon = ({
11
11
  checked?: boolean;
12
12
  onClick?: () => void;
13
13
  }) => (
14
+ // oxlint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- the control that renders the icon handles the keyboard
14
15
  <span className={className} onClick={onClick}>
15
16
  {checked ? (
16
17
  <svg
@@ -6,6 +6,7 @@ import type { IconProps } from '@redocly/theme/icons/types';
6
6
  import { getCssColorVariable } from '@redocly/theme/core/utils';
7
7
 
8
8
  const Icon = ({ className, onClick }: IconProps & { onClick?: () => void }) => (
9
+ // oxlint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- the control that renders the icon handles the keyboard
9
10
  <svg
10
11
  className={className}
11
12
  onClick={onClick}
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-height) - var(--banner-height));
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 { useSearch } = useThemeHooks();
17
- const { askAi } = useSearch();
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);