@@ -10,10 +10,13 @@ import NavbarLogo from '@theme/Navbar/Logo';
10
10
import ColorModeToggle from "../../components/ColorModeToggler" ;
11
11
import Translate from "@docusaurus/Translate" ;
12
12
import { useLocation } from '@docusaurus/router' ;
13
+ import { useHistory } from '@docusaurus/router' ;
13
14
import MobileLanguagePicker from "./MobileLanguagePicker" ;
15
+
14
16
const MobileSideBarMenuContents = ( { className, onClick, onClose, sidebar, path, menu, isVisible = true } ) => {
15
17
const [ showTopLevel , setShowTopLevel ] = useState ( false ) ;
16
18
const location = useLocation ( ) ;
19
+ const history = useHistory ( ) ;
17
20
18
21
// Reset to sidebar view (showTopLevel = false) whenever the mobile menu becomes visible
19
22
useEffect ( ( ) => {
@@ -22,12 +25,60 @@ const MobileSideBarMenuContents = ({ className, onClick, onClose, sidebar, path,
22
25
}
23
26
} , [ isVisible ] ) ;
24
27
28
+ // Get current locale from URL
29
+ const getCurrentLocale = ( ) => {
30
+ const pathname = location . pathname ;
31
+ const docsLocaleMatch = pathname . match ( / ^ \/ d o c s \/ ( j p | j a | r u | z h | z h - C N ) (? = \/ | $ ) / ) ;
32
+ return docsLocaleMatch ? docsLocaleMatch [ 1 ] : 'en' ;
33
+ } ;
34
+
35
+ // Normalize path for comparison (remove locale prefix if present)
36
+ const normalizePath = ( path ) => {
37
+ if ( ! path ) return '' ;
38
+ // Remove locale prefix from path for comparison
39
+ return path . replace ( / ^ \/ d o c s \/ ( j p | j a | r u | z h | z h - C N ) / , '/docs' ) ;
40
+ } ;
41
+
42
+ // Check if the current path exists in the sidebar
43
+ const isCurrentPathInSidebar = ( ) => {
44
+ if ( ! sidebar || sidebar . length === 0 ) return false ;
45
+
46
+ const normalizedCurrentPath = normalizePath ( location . pathname ) ;
47
+
48
+ const checkItemsRecursively = ( items ) => {
49
+ return items . some ( item => {
50
+ // Check if this item matches the current path
51
+ const itemHref = item . href || ( item . customProps && item . customProps . href ) ;
52
+ if ( itemHref ) {
53
+ const normalizedItemHref = normalizePath ( itemHref ) ;
54
+ if ( normalizedCurrentPath === normalizedItemHref || normalizedCurrentPath . startsWith ( normalizedItemHref + '/' ) ) {
55
+ return true ;
56
+ }
57
+ }
58
+
59
+ // Check children recursively
60
+ if ( item . items && item . items . length > 0 ) {
61
+ return checkItemsRecursively ( item . items ) ;
62
+ }
63
+
64
+ return false ;
65
+ } ) ;
66
+ } ;
67
+
68
+ return checkItemsRecursively ( sidebar ) ;
69
+ } ;
70
+
25
71
// Check if we're on a docs root page (should show only top-level menu)
26
72
const isDocsRootPage = ( ) => {
27
73
const docsRootPaths = [ '/docs/' , '/docs/jp/' , '/docs/ru/' , '/docs/zh/' ] ;
28
74
return docsRootPaths . includes ( location . pathname ) ;
29
75
} ;
30
76
77
+ // Check if we should show the main menu instead of sidebar
78
+ const shouldShowMainMenu = ( ) => {
79
+ return isDocsRootPage ( ) || ! isCurrentPathInSidebar ( ) ;
80
+ } ;
81
+
31
82
// Find which top-level category we're currently in
32
83
const getCurrentCategory = ( ) => {
33
84
if ( ! menu || ! path ) return null ;
@@ -44,17 +95,42 @@ const MobileSideBarMenuContents = ({ className, onClick, onClose, sidebar, path,
44
95
45
96
const currentCategory = getCurrentCategory ( ) ;
46
97
47
- // Handle item click - close the mobile sidebar
98
+ // Handle item click - navigate and potentially close the mobile sidebar
48
99
const handleItemClick = ( item ) => {
100
+ // Handle navigation for items with href
101
+ let itemHref = item . href || ( item . customProps && item . customProps . href ) ;
102
+
103
+ if ( itemHref ) {
104
+ // Fix URLs for main menu items - add /docs/ prefix if missing and handle localization
105
+ // Use shouldShowMainMenu() instead of showTopLevel to catch invalid pages too
106
+ if ( shouldShowMainMenu ( ) && itemHref && ! itemHref . startsWith ( '/docs/' ) && ! itemHref . startsWith ( 'http' ) ) {
107
+ const currentLocale = getCurrentLocale ( ) ;
108
+ if ( currentLocale !== 'en' ) {
109
+ itemHref = `/docs/${ currentLocale } ${ itemHref } ` ;
110
+ } else {
111
+ itemHref = `/docs${ itemHref } ` ;
112
+ }
113
+ }
114
+
115
+ // Navigate to the href
116
+ if ( itemHref . startsWith ( 'http' ) ) {
117
+ // External link
118
+ window . open ( itemHref , '_blank' , 'noopener,noreferrer' ) ;
119
+ } else {
120
+ // Internal link
121
+ history . push ( itemHref ) ;
122
+ }
123
+
124
+ // Close the menu after navigation
125
+ if ( onClose ) {
126
+ onClose ( ) ;
127
+ }
128
+ }
129
+
49
130
// Call the onClick handler from parent if provided
50
131
if ( onClick ) {
51
132
onClick ( item ) ;
52
133
}
53
-
54
- // For non-collapsible items, close the menu
55
- if ( item && ! item . collapsible && onClose ) {
56
- onClose ( ) ;
57
- }
58
134
} ;
59
135
60
136
// Generic function to render CustomSidebarItems with consistent styling
@@ -79,7 +155,7 @@ const MobileSideBarMenuContents = ({ className, onClick, onClose, sidebar, path,
79
155
80
156
// Render the enhanced header with logo and navigation toggle
81
157
const renderHeader = ( ) => {
82
- const isTopLevel = showTopLevel || isDocsRootPage ( ) ;
158
+ const isTopLevel = showTopLevel || shouldShowMainMenu ( ) ;
83
159
84
160
return (
85
161
< div className = { clsx ( "navbar-sidebar__brand" , styles . docsMobileMenu_header ) } >
@@ -97,7 +173,7 @@ const MobileSideBarMenuContents = ({ className, onClick, onClose, sidebar, path,
97
173
</ div >
98
174
</ div >
99
175
< div className = { styles . bottomLevel } >
100
- { ! isDocsRootPage ( ) && (
176
+ { ! shouldShowMainMenu ( ) && (
101
177
< button
102
178
className = { styles . levelToggleButton }
103
179
onClick = { ( ) => setShowTopLevel ( ! showTopLevel ) }
@@ -145,8 +221,8 @@ const MobileSideBarMenuContents = ({ className, onClick, onClose, sidebar, path,
145
221
) ;
146
222
} ;
147
223
148
- // If we're on a docs root page, always show the top-level menu
149
- if ( isDocsRootPage ( ) ) {
224
+ // If we're on a docs root page or invalid path , always show the top-level menu
225
+ if ( shouldShowMainMenu ( ) ) {
150
226
return (
151
227
< div className = { clsx ( styles . docsMobileMenu , className ) } >
152
228
{ renderTopLevelMenu ( ) }
0 commit comments