1
- import { matchRoutes , removeBase , useLocation } from '@rspress/runtime' ;
1
+ import { useLocation } from '@rspress/runtime' ;
2
2
import {
3
3
type SidebarDivider as ISidebarDivider ,
4
4
type SidebarItem as ISidebarItem ,
5
5
type SidebarSectionHeader as ISidebarSectionHeader ,
6
6
type NormalizedSidebarGroup ,
7
7
inBrowser ,
8
- normalizeSlash ,
9
8
} from '@rspress/shared' ;
10
9
import { useEffect , useState } from 'react' ;
11
- import { routes } from 'virtual-routes' ;
12
- import { isActive , useLocaleSiteData , useSidebarData } from '../../logic' ;
10
+ import { useSidebarData } from '../../logic' ;
13
11
14
12
import type { UISwitchResult } from '../../logic/useUISwitch' ;
15
13
import { NavBarTitle } from '../Nav/NavBarTitle' ;
@@ -22,6 +20,7 @@ import {
22
20
isSideBarCustomLink ,
23
21
isSidebarDivider ,
24
22
isSidebarSectionHeader ,
23
+ useActiveMatcher ,
25
24
} from './utils' ;
26
25
27
26
export interface SidebarItemProps {
@@ -45,7 +44,11 @@ interface Props {
45
44
navTitle ?: React . ReactNode ;
46
45
}
47
46
48
- type SidebarData = ( ISidebarDivider | ISidebarItem | NormalizedSidebarGroup ) [ ] ;
47
+ export type SidebarData = (
48
+ | ISidebarDivider
49
+ | ISidebarItem
50
+ | NormalizedSidebarGroup
51
+ ) [ ] ;
49
52
50
53
export const highlightTitleStyle = {
51
54
fontSize : '14px' ,
@@ -72,9 +75,9 @@ export function Sidebar(props: Props) {
72
75
return rawSidebarData . filter ( Boolean ) . flat ( ) ;
73
76
} ) ;
74
77
75
- const localesData = useLocaleSiteData ( ) ;
76
78
const pathname = decodeURIComponent ( rawPathname ) ;
77
- const langRoutePrefix = normalizeSlash ( localesData . langRoutePrefix || '' ) ;
79
+
80
+ const activeMatcher = useActiveMatcher ( ) ;
78
81
79
82
useEffect ( ( ) => {
80
83
if ( inBrowser ( ) ) {
@@ -133,73 +136,6 @@ export function Sidebar(props: Props) {
133
136
setSidebarData ( newSidebarData ) ;
134
137
} , [ rawSidebarData , pathname ] ) ;
135
138
136
- const removeLangPrefix = ( path : string ) => {
137
- return path . replace ( langRoutePrefix , '' ) ;
138
- } ;
139
- const activeMatcher = ( path : string ) => {
140
- return isActive (
141
- removeBase ( removeLangPrefix ( pathname ) ) ,
142
- removeLangPrefix ( path ) ,
143
- true ,
144
- ) ;
145
- } ;
146
-
147
- const renderItem = (
148
- item :
149
- | NormalizedSidebarGroup
150
- | ISidebarItem
151
- | ISidebarDivider
152
- | ISidebarSectionHeader ,
153
- index : number ,
154
- ) => {
155
- if ( isSidebarDivider ( item ) ) {
156
- return (
157
- < SidebarDivider key = { index } depth = { 0 } dividerType = { item . dividerType } />
158
- ) ;
159
- }
160
-
161
- if ( isSidebarSectionHeader ( item ) ) {
162
- return (
163
- < SidebarSectionHeader
164
- key = { index }
165
- sectionHeaderText = { item . sectionHeaderText }
166
- tag = { item . tag }
167
- />
168
- ) ;
169
- }
170
-
171
- if ( isSideBarCustomLink ( item ) ) {
172
- return (
173
- < div
174
- className = "rspress-sidebar-item rspress-sidebar-custom-link"
175
- key = { index }
176
- data-context = { item . context }
177
- >
178
- < SidebarItem
179
- id = { String ( index ) }
180
- item = { item }
181
- depth = { 0 }
182
- activeMatcher = { activeMatcher }
183
- key = { index }
184
- collapsed = { ( item as NormalizedSidebarGroup ) . collapsed ?? true }
185
- setSidebarData = { setSidebarData }
186
- />
187
- </ div >
188
- ) ;
189
- }
190
-
191
- return (
192
- < SidebarItem
193
- id = { String ( index ) }
194
- item = { item }
195
- depth = { 0 }
196
- activeMatcher = { activeMatcher }
197
- key = { index }
198
- collapsed = { ( item as NormalizedSidebarGroup ) . collapsed ?? true }
199
- setSidebarData = { setSidebarData }
200
- />
201
- ) ;
202
- } ;
203
139
return (
204
140
< aside
205
141
className = { `${ styles . sidebar } rspress-sidebar ${
@@ -212,10 +148,98 @@ export function Sidebar(props: Props) {
212
148
< div className = { `rspress-scrollbar ${ styles . sidebarContent } ` } >
213
149
< nav className = "pb-2" >
214
150
{ beforeSidebar }
215
- { sidebarData . map ( renderItem ) }
151
+ < SidebarList
152
+ sidebarData = { sidebarData }
153
+ setSidebarData = { setSidebarData }
154
+ />
216
155
{ afterSidebar }
217
156
</ nav >
218
157
</ div >
219
158
</ aside >
220
159
) ;
221
160
}
161
+
162
+ export function SidebarList ( {
163
+ sidebarData,
164
+ setSidebarData,
165
+ } : {
166
+ sidebarData : SidebarData ;
167
+ setSidebarData : React . Dispatch < React . SetStateAction < SidebarData > > ;
168
+ } ) {
169
+ const activeMatcher = useActiveMatcher ( ) ;
170
+ return (
171
+ < >
172
+ { sidebarData . map ( ( item , index ) => {
173
+ return (
174
+ < SidebarListItem
175
+ key = { index }
176
+ item = { item }
177
+ index = { index }
178
+ setSidebarData = { setSidebarData }
179
+ activeMatcher = { activeMatcher }
180
+ />
181
+ ) ;
182
+ } ) }
183
+ </ >
184
+ ) ;
185
+ }
186
+
187
+ function SidebarListItem ( props : {
188
+ item :
189
+ | NormalizedSidebarGroup
190
+ | ISidebarItem
191
+ | ISidebarDivider
192
+ | ISidebarSectionHeader ;
193
+ index : number ;
194
+ setSidebarData : React . Dispatch < React . SetStateAction < SidebarData > > ;
195
+ activeMatcher : ( link : string ) => boolean ;
196
+ } ) {
197
+ const { item, index, setSidebarData, activeMatcher } = props ;
198
+ if ( isSidebarDivider ( item ) ) {
199
+ return (
200
+ < SidebarDivider key = { index } depth = { 0 } dividerType = { item . dividerType } />
201
+ ) ;
202
+ }
203
+
204
+ if ( isSidebarSectionHeader ( item ) ) {
205
+ return (
206
+ < SidebarSectionHeader
207
+ key = { index }
208
+ sectionHeaderText = { item . sectionHeaderText }
209
+ tag = { item . tag }
210
+ />
211
+ ) ;
212
+ }
213
+
214
+ if ( isSideBarCustomLink ( item ) ) {
215
+ return (
216
+ < div
217
+ className = "rspress-sidebar-item rspress-sidebar-custom-link"
218
+ key = { index }
219
+ data-context = { item . context }
220
+ >
221
+ < SidebarItem
222
+ id = { String ( index ) }
223
+ item = { item }
224
+ depth = { 0 }
225
+ key = { index }
226
+ collapsed = { ( item as NormalizedSidebarGroup ) . collapsed ?? true }
227
+ setSidebarData = { setSidebarData }
228
+ activeMatcher = { activeMatcher }
229
+ />
230
+ </ div >
231
+ ) ;
232
+ }
233
+
234
+ return (
235
+ < SidebarItem
236
+ id = { String ( index ) }
237
+ item = { item }
238
+ depth = { 0 }
239
+ key = { index }
240
+ activeMatcher = { activeMatcher }
241
+ collapsed = { ( item as NormalizedSidebarGroup ) . collapsed ?? true }
242
+ setSidebarData = { setSidebarData }
243
+ />
244
+ ) ;
245
+ }
0 commit comments