@docusaurus/theme-classic 0.0.0-4735 → 0.0.0-4736

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 (33) hide show
  1. package/lib/theme-classic.d.ts +59 -1
  2. package/lib-next/theme/DocSidebar/Mobile/index.js +24 -20
  3. package/lib-next/theme/LayoutProviders/index.js +4 -6
  4. package/lib-next/theme/Navbar/ColorModeToggle/index.js +25 -0
  5. package/lib-next/theme/Navbar/Content/index.js +70 -0
  6. package/lib-next/theme/Navbar/Content/styles.module.css +15 -0
  7. package/lib-next/theme/Navbar/Layout/index.js +54 -0
  8. package/lib-next/theme/Navbar/{styles.module.css → Layout/styles.module.css} +0 -13
  9. package/lib-next/theme/Navbar/Logo/index.js +17 -0
  10. package/lib-next/theme/Navbar/MobileSidebar/Header/index.js +33 -0
  11. package/lib-next/theme/Navbar/MobileSidebar/Layout/index.js +28 -0
  12. package/lib-next/theme/Navbar/MobileSidebar/PrimaryMenu/index.js +33 -0
  13. package/lib-next/theme/Navbar/MobileSidebar/SecondaryMenu/index.js +36 -0
  14. package/lib-next/theme/Navbar/MobileSidebar/Toggle/index.js +23 -0
  15. package/lib-next/theme/Navbar/MobileSidebar/index.js +31 -0
  16. package/lib-next/theme/Navbar/index.js +6 -273
  17. package/package.json +13 -13
  18. package/src/theme/DocSidebar/Mobile/index.tsx +26 -23
  19. package/src/theme/LayoutProviders/index.tsx +4 -6
  20. package/src/theme/Navbar/ColorModeToggle/index.tsx +30 -0
  21. package/src/theme/Navbar/Content/index.tsx +81 -0
  22. package/src/theme/Navbar/Content/styles.module.css +15 -0
  23. package/src/theme/Navbar/Layout/index.tsx +57 -0
  24. package/src/theme/Navbar/{styles.module.css → Layout/styles.module.css} +0 -13
  25. package/src/theme/Navbar/Logo/index.tsx +19 -0
  26. package/src/theme/Navbar/MobileSidebar/Header/index.tsx +34 -0
  27. package/src/theme/Navbar/MobileSidebar/Layout/index.tsx +31 -0
  28. package/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx +38 -0
  29. package/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx +38 -0
  30. package/src/theme/Navbar/MobileSidebar/Toggle/index.tsx +25 -0
  31. package/src/theme/Navbar/MobileSidebar/index.tsx +33 -0
  32. package/src/theme/Navbar/index.tsx +6 -292
  33. package/src/theme-classic.d.ts +59 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from 'react';
9
+ import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
10
+ import IconClose from '@theme/IconClose';
11
+ import NavbarLogo from '@theme/Navbar/Logo';
12
+ import {useNavbarMobileSidebar} from '@docusaurus/theme-common';
13
+
14
+ function CloseButton() {
15
+ const mobileSidebar = useNavbarMobileSidebar();
16
+ return (
17
+ <button
18
+ type="button"
19
+ className="clean-btn navbar-sidebar__close"
20
+ onClick={() => mobileSidebar.toggle()}>
21
+ <IconClose color="var(--ifm-color-emphasis-600)" />
22
+ </button>
23
+ );
24
+ }
25
+
26
+ export default function NavbarMobileSidebarHeader(): JSX.Element {
27
+ return (
28
+ <div className="navbar-sidebar__brand">
29
+ <NavbarLogo />
30
+ <NavbarColorModeToggle className="margin-right--md" />
31
+ <CloseButton />
32
+ </div>
33
+ );
34
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from 'react';
9
+ import clsx from 'clsx';
10
+ import type {Props} from '@theme/Navbar/MobileSidebar/Layout';
11
+ import {useNavbarSecondaryMenu} from '@docusaurus/theme-common';
12
+
13
+ export default function NavbarMobileSidebarLayout({
14
+ header,
15
+ primaryMenu,
16
+ secondaryMenu,
17
+ }: Props): JSX.Element {
18
+ const {shown: secondaryMenuShown} = useNavbarSecondaryMenu();
19
+ return (
20
+ <div className="navbar-sidebar">
21
+ {header}
22
+ <div
23
+ className={clsx('navbar-sidebar__items', {
24
+ 'navbar-sidebar__items--show-secondary': secondaryMenuShown,
25
+ })}>
26
+ <div className="navbar-sidebar__item menu">{primaryMenu}</div>
27
+ <div className="navbar-sidebar__item menu">{secondaryMenu}</div>
28
+ </div>
29
+ </div>
30
+ );
31
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from 'react';
9
+ import {useNavbarMobileSidebar, useThemeConfig} from '@docusaurus/theme-common';
10
+ import type {Props as NavbarItemConfig} from '@theme/NavbarItem';
11
+ import NavbarItem from '../../../NavbarItem';
12
+
13
+ function useNavbarItems() {
14
+ // TODO temporary casting until ThemeConfig type is improved
15
+ return useThemeConfig().navbar.items as NavbarItemConfig[];
16
+ }
17
+
18
+ // The primary menu displays the navbar items
19
+ export default function NavbarMobilePrimaryMenu(): JSX.Element {
20
+ const mobileSidebar = useNavbarMobileSidebar();
21
+
22
+ // TODO how can the order be defined for mobile?
23
+ // Should we allow providing a different list of items?
24
+ const items = useNavbarItems();
25
+
26
+ return (
27
+ <ul className="menu__list">
28
+ {items.map((item, i) => (
29
+ <NavbarItem
30
+ mobile
31
+ {...item}
32
+ onClick={() => mobileSidebar.toggle()}
33
+ key={i}
34
+ />
35
+ ))}
36
+ </ul>
37
+ );
38
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React, {type ComponentProps} from 'react';
9
+ import {useNavbarSecondaryMenu, useThemeConfig} from '@docusaurus/theme-common';
10
+ import Translate from '@docusaurus/Translate';
11
+
12
+ function SecondaryMenuBackButton(props: ComponentProps<'button'>) {
13
+ return (
14
+ <button {...props} type="button" className="clean-btn navbar-sidebar__back">
15
+ <Translate
16
+ id="theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel"
17
+ description="The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)">
18
+ ← Back to main menu
19
+ </Translate>
20
+ </button>
21
+ );
22
+ }
23
+
24
+ // The secondary menu slides from the right and shows contextual information
25
+ // such as the docs sidebar
26
+ export default function NavbarMobileSidebarSecondaryMenu(): JSX.Element | null {
27
+ const isPrimaryMenuEmpty = useThemeConfig().navbar.items.length === 0;
28
+ const secondaryMenu = useNavbarSecondaryMenu();
29
+ return (
30
+ <>
31
+ {/* edge-case: prevent returning to the primaryMenu when it's empty */}
32
+ {!isPrimaryMenuEmpty && (
33
+ <SecondaryMenuBackButton onClick={() => secondaryMenu.hide()} />
34
+ )}
35
+ {secondaryMenu.content}
36
+ </>
37
+ );
38
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from 'react';
9
+ import IconMenu from '@theme/IconMenu';
10
+ import {useNavbarMobileSidebar} from '@docusaurus/theme-common';
11
+
12
+ export default function MobileSidebarToggle(): JSX.Element {
13
+ const mobileSidebar = useNavbarMobileSidebar();
14
+ return (
15
+ <button
16
+ onClick={mobileSidebar.toggle}
17
+ onKeyDown={mobileSidebar.toggle}
18
+ aria-label="Navigation bar toggle"
19
+ className="navbar__toggle clean-btn"
20
+ type="button"
21
+ tabIndex={0}>
22
+ <IconMenu />
23
+ </button>
24
+ );
25
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from 'react';
9
+ import NavbarMobileSidebarLayout from '@theme/Navbar/MobileSidebar/Layout';
10
+ import NavbarMobileSidebarHeader from '@theme/Navbar/MobileSidebar/Header';
11
+ import {
12
+ useLockBodyScroll,
13
+ useNavbarMobileSidebar,
14
+ } from '@docusaurus/theme-common';
15
+ import NavbarMobileSidebarPrimaryMenu from '@theme/Navbar/MobileSidebar/PrimaryMenu';
16
+ import NavbarMobileSidebarSecondaryMenu from '@theme/Navbar/MobileSidebar/SecondaryMenu';
17
+
18
+ export default function NavbarMobileSidebar(): JSX.Element | null {
19
+ const mobileSidebar = useNavbarMobileSidebar();
20
+ useLockBodyScroll(mobileSidebar.shown);
21
+
22
+ if (!mobileSidebar.shouldRender) {
23
+ return null;
24
+ }
25
+
26
+ return (
27
+ <NavbarMobileSidebarLayout
28
+ header={<NavbarMobileSidebarHeader />}
29
+ primaryMenu={<NavbarMobileSidebarPrimaryMenu />}
30
+ secondaryMenu={<NavbarMobileSidebarSecondaryMenu />}
31
+ />
32
+ );
33
+ }
@@ -5,300 +5,14 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import React, {useCallback, useState, useEffect} from 'react';
9
- import clsx from 'clsx';
10
- import Translate from '@docusaurus/Translate';
11
- import SearchBar from '@theme/SearchBar';
12
- import ColorModeToggle from '@theme/ColorModeToggle';
13
- import {
14
- useThemeConfig,
15
- useMobileSecondaryMenuRenderer,
16
- usePrevious,
17
- useHistoryPopHandler,
18
- useHideableNavbar,
19
- useLockBodyScroll,
20
- useWindowSize,
21
- useColorMode,
22
- } from '@docusaurus/theme-common';
23
- import {useActivePlugin} from '@docusaurus/plugin-content-docs/client';
24
- import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
25
- import Logo from '@theme/Logo';
26
- import IconMenu from '@theme/IconMenu';
27
- import IconClose from '@theme/IconClose';
28
-
29
- import styles from './styles.module.css';
30
-
31
- // retrocompatible with v1
32
- const DefaultNavItemPosition = 'right';
33
-
34
- function useNavbarItems() {
35
- // TODO temporary casting until ThemeConfig type is improved
36
- return useThemeConfig().navbar.items as NavbarItemConfig[];
37
- }
38
-
39
- // If split links by left/right
40
- // if position is unspecified, fallback to right (as v1)
41
- function splitNavItemsByPosition(items: NavbarItemConfig[]) {
42
- const leftItems = items.filter(
43
- (item) => (item.position ?? DefaultNavItemPosition) === 'left',
44
- );
45
- const rightItems = items.filter(
46
- (item) => (item.position ?? DefaultNavItemPosition) === 'right',
47
- );
48
- return {
49
- leftItems,
50
- rightItems,
51
- };
52
- }
53
-
54
- function useMobileSidebar() {
55
- const windowSize = useWindowSize();
56
-
57
- // Mobile sidebar not visible on hydration: can avoid SSR rendering
58
- const shouldRender = windowSize === 'mobile'; // || windowSize === 'ssr';
59
-
60
- const [shown, setShown] = useState(false);
61
-
62
- // Close mobile sidebar on navigation pop
63
- // Most likely firing when using the Android back button (but not only)
64
- useHistoryPopHandler(() => {
65
- if (shown) {
66
- setShown(false);
67
- // Should we prevent the navigation here?
68
- // See https://github.com/facebook/docusaurus/pull/5462#issuecomment-911699846
69
- return false; // prevent pop navigation
70
- }
71
- return undefined;
72
- });
73
-
74
- const toggle = useCallback(() => {
75
- setShown((s) => !s);
76
- }, []);
77
-
78
- useEffect(() => {
79
- if (windowSize === 'desktop') {
80
- setShown(false);
81
- }
82
- }, [windowSize]);
83
-
84
- return {shouldRender, toggle, shown};
85
- }
86
-
87
- function useColorModeToggle() {
88
- const {
89
- colorMode: {disableSwitch},
90
- } = useThemeConfig();
91
- const {colorMode, setColorMode} = useColorMode();
92
- return {
93
- value: colorMode,
94
- onChange: setColorMode,
95
- disabled: disableSwitch,
96
- };
97
- }
98
-
99
- function useSecondaryMenu({
100
- sidebarShown,
101
- toggleSidebar,
102
- }: NavbarMobileSidebarProps) {
103
- const content = useMobileSecondaryMenuRenderer()?.({
104
- toggleSidebar,
105
- });
106
- const previousContent = usePrevious(content);
107
-
108
- const [shown, setShown] = useState<boolean>(
109
- () =>
110
- // /!\ content is set with useEffect,
111
- // so it's not available on mount anyway
112
- // "return !!content" => always returns false
113
- false,
114
- );
115
-
116
- // When content is become available for the first time (set in useEffect)
117
- // we set this content to be shown!
118
- useEffect(() => {
119
- const contentBecameAvailable = content && !previousContent;
120
- if (contentBecameAvailable) {
121
- setShown(true);
122
- }
123
- }, [content, previousContent]);
124
-
125
- const hasContent = !!content;
126
-
127
- // On sidebar close, secondary menu is set to be shown on next re-opening
128
- // (if any secondary menu content available)
129
- useEffect(() => {
130
- if (!hasContent) {
131
- setShown(false);
132
- return;
133
- }
134
- if (!sidebarShown) {
135
- setShown(true);
136
- }
137
- }, [sidebarShown, hasContent]);
138
-
139
- const hide = useCallback(() => {
140
- setShown(false);
141
- }, []);
142
-
143
- return {shown, hide, content};
144
- }
145
-
146
- type NavbarMobileSidebarProps = {
147
- sidebarShown: boolean;
148
- toggleSidebar: () => void;
149
- };
150
-
151
- function NavbarMobileSidebar({
152
- sidebarShown,
153
- toggleSidebar,
154
- }: NavbarMobileSidebarProps) {
155
- useLockBodyScroll(sidebarShown);
156
- const items = useNavbarItems();
157
-
158
- const colorModeToggle = useColorModeToggle();
159
-
160
- const secondaryMenu = useSecondaryMenu({
161
- sidebarShown,
162
- toggleSidebar,
163
- });
164
-
165
- return (
166
- <div className="navbar-sidebar">
167
- <div className="navbar-sidebar__brand">
168
- <Logo
169
- className="navbar__brand"
170
- imageClassName="navbar__logo"
171
- titleClassName="navbar__title"
172
- />
173
- {!colorModeToggle.disabled && (
174
- <ColorModeToggle
175
- className={styles.navbarSidebarToggle}
176
- value={colorModeToggle.value}
177
- onChange={colorModeToggle.onChange}
178
- />
179
- )}
180
- <button
181
- type="button"
182
- className="clean-btn navbar-sidebar__close"
183
- onClick={toggleSidebar}>
184
- <IconClose
185
- color="var(--ifm-color-emphasis-600)"
186
- className={styles.navbarSidebarCloseSvg}
187
- />
188
- </button>
189
- </div>
190
-
191
- <div
192
- className={clsx('navbar-sidebar__items', {
193
- 'navbar-sidebar__items--show-secondary': secondaryMenu.shown,
194
- })}>
195
- <div className="navbar-sidebar__item menu">
196
- <ul className="menu__list">
197
- {items.map((item, i) => (
198
- <NavbarItem mobile {...item} onClick={toggleSidebar} key={i} />
199
- ))}
200
- </ul>
201
- </div>
202
-
203
- <div className="navbar-sidebar__item menu">
204
- {items.length > 0 && (
205
- <button
206
- type="button"
207
- className="clean-btn navbar-sidebar__back"
208
- onClick={secondaryMenu.hide}>
209
- <Translate
210
- id="theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel"
211
- description="The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)">
212
- ← Back to main menu
213
- </Translate>
214
- </button>
215
- )}
216
- {secondaryMenu.content}
217
- </div>
218
- </div>
219
- </div>
220
- );
221
- }
8
+ import React from 'react';
9
+ import NavbarLayout from '@theme/Navbar/Layout';
10
+ import NavbarContent from '@theme/Navbar/Content';
222
11
 
223
12
  export default function Navbar(): JSX.Element {
224
- const {
225
- navbar: {hideOnScroll, style},
226
- } = useThemeConfig();
227
-
228
- const mobileSidebar = useMobileSidebar();
229
- const colorModeToggle = useColorModeToggle();
230
- const activeDocPlugin = useActivePlugin();
231
- const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);
232
-
233
- const items = useNavbarItems();
234
- const hasSearchNavbarItem = items.some((item) => item.type === 'search');
235
- const {leftItems, rightItems} = splitNavItemsByPosition(items);
236
-
237
13
  return (
238
- <nav
239
- ref={navbarRef}
240
- className={clsx(
241
- 'navbar',
242
- 'navbar--fixed-top',
243
- hideOnScroll && [
244
- styles.navbarHideable,
245
- !isNavbarVisible && styles.navbarHidden,
246
- ],
247
- {
248
- 'navbar--dark': style === 'dark',
249
- 'navbar--primary': style === 'primary',
250
- 'navbar-sidebar--show': mobileSidebar.shown,
251
- },
252
- )}>
253
- <div className="navbar__inner">
254
- <div className="navbar__items">
255
- {(items?.length > 0 || activeDocPlugin) && (
256
- <button
257
- aria-label="Navigation bar toggle"
258
- className="navbar__toggle clean-btn"
259
- type="button"
260
- tabIndex={0}
261
- onClick={mobileSidebar.toggle}
262
- onKeyDown={mobileSidebar.toggle}>
263
- <IconMenu />
264
- </button>
265
- )}
266
- <Logo
267
- className="navbar__brand"
268
- imageClassName="navbar__logo"
269
- titleClassName="navbar__title"
270
- />
271
- {leftItems.map((item, i) => (
272
- <NavbarItem {...item} key={i} />
273
- ))}
274
- </div>
275
- <div className="navbar__items navbar__items--right">
276
- {rightItems.map((item, i) => (
277
- <NavbarItem {...item} key={i} />
278
- ))}
279
- {!colorModeToggle.disabled && (
280
- <ColorModeToggle
281
- className={styles.toggle}
282
- value={colorModeToggle.value}
283
- onChange={colorModeToggle.onChange}
284
- />
285
- )}
286
- {!hasSearchNavbarItem && <SearchBar />}
287
- </div>
288
- </div>
289
-
290
- <div
291
- role="presentation"
292
- className="navbar-sidebar__backdrop"
293
- onClick={mobileSidebar.toggle}
294
- />
295
-
296
- {mobileSidebar.shouldRender && (
297
- <NavbarMobileSidebar
298
- sidebarShown={mobileSidebar.shown}
299
- toggleSidebar={mobileSidebar.toggle}
300
- />
301
- )}
302
- </nav>
14
+ <NavbarLayout>
15
+ <NavbarContent />
16
+ </NavbarLayout>
303
17
  );
304
18
  }
@@ -460,6 +460,64 @@ declare module '@theme/Navbar' {
460
460
  export default function Navbar(): JSX.Element;
461
461
  }
462
462
 
463
+ declare module '@theme/Navbar/ColorModeToggle' {
464
+ export interface Props {
465
+ readonly className?: string;
466
+ }
467
+
468
+ export default function NavbarColorModeToggle(
469
+ props: Props,
470
+ ): JSX.Element | null;
471
+ }
472
+
473
+ declare module '@theme/Navbar/Logo' {
474
+ export default function NavbarLogo(): JSX.Element;
475
+ }
476
+
477
+ declare module '@theme/Navbar/Content' {
478
+ export default function NavbarContent(): JSX.Element;
479
+ }
480
+
481
+ declare module '@theme/Navbar/Layout' {
482
+ export interface Props {
483
+ children: React.ReactNode;
484
+ }
485
+
486
+ export default function NavbarLayout(props: Props): JSX.Element;
487
+ }
488
+
489
+ declare module '@theme/Navbar/MobileSidebar' {
490
+ export default function NavbarMobileSidebar(): JSX.Element;
491
+ }
492
+
493
+ declare module '@theme/Navbar/MobileSidebar/Layout' {
494
+ import type {ReactNode} from 'react';
495
+
496
+ interface Props {
497
+ header: ReactNode;
498
+ primaryMenu: ReactNode;
499
+ secondaryMenu: ReactNode;
500
+ }
501
+
502
+ export default function NavbarMobileSidebarLayout(props: Props): JSX.Element;
503
+ }
504
+
505
+ declare module '@theme/Navbar/MobileSidebar/Toggle' {
506
+ export default function NavbarMobileSidebarToggle(): JSX.Element;
507
+ }
508
+
509
+ declare module '@theme/Navbar/MobileSidebar/PrimaryMenu' {
510
+ export default function NavbarMobileSidebarPrimaryMenu(): JSX.Element;
511
+ }
512
+
513
+ declare module '@theme/Navbar/MobileSidebar/SecondaryMenu' {
514
+ export default function NavbarMobileSidebarSecondaryMenu(): JSX.Element;
515
+ }
516
+
517
+ declare module '@theme/Navbar/MobileSidebar/Header' {
518
+ export default function NavbarMobileSidebarHeader(): JSX.Element;
519
+ }
520
+
463
521
  declare module '@theme/NavbarItem/DefaultNavbarItem' {
464
522
  import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink';
465
523
 
@@ -758,7 +816,7 @@ declare module '@theme/ColorModeToggle' {
758
816
  readonly onChange: (colorMode: ColorMode) => void;
759
817
  }
760
818
 
761
- export default function Toggle(props: Props): JSX.Element;
819
+ export default function ColorModeToggle(props: Props): JSX.Element;
762
820
  }
763
821
 
764
822
  declare module '@theme/Logo' {