@@ -305,27 +305,70 @@ export class DefaultTheme extends Theme {
305
305
return parent . groups . map ( toNavigation ) ;
306
306
}
307
307
308
+ if (
309
+ opts . includeFolders &&
310
+ parent . children ?. every ( ( child ) => child . kindOf ( ReflectionKind . Module ) ) &&
311
+ parent . children . some ( ( child ) => child . name . includes ( "/" ) )
312
+ ) {
313
+ return deriveModuleFolders ( parent . children ) ;
314
+ }
315
+
308
316
return parent . children ?. map ( toNavigation ) ;
309
317
}
310
318
311
- function shouldShowCategories (
312
- reflection : Reflection ,
313
- opts : { includeCategories : boolean ; includeGroups : boolean } ,
314
- ) {
315
- if ( opts . includeCategories ) {
316
- return ! reflection . comment ?. hasModifier ( "@hideCategories" ) ;
319
+ function deriveModuleFolders ( children : DeclarationReflection [ ] ) {
320
+ const result : NavigationElement [ ] = [ ] ;
321
+
322
+ const resolveOrCreateParents = (
323
+ path : string [ ] ,
324
+ root : NavigationElement [ ] = result ,
325
+ ) : NavigationElement [ ] => {
326
+ if ( path . length > 1 ) {
327
+ const inner = root . find ( ( el ) => el . text === path [ 0 ] ) ;
328
+ if ( inner ) {
329
+ inner . children ||= [ ] ;
330
+ return resolveOrCreateParents ( path . slice ( 1 ) , inner . children ) ;
331
+ } else {
332
+ root . push ( {
333
+ text : path [ 0 ] ,
334
+ children : [ ] ,
335
+ } ) ;
336
+ return resolveOrCreateParents ( path . slice ( 1 ) , root [ root . length - 1 ] . children ) ;
337
+ }
338
+ }
339
+
340
+ return root ;
341
+ } ;
342
+
343
+ // Note: This might end up putting a module within another module if we document
344
+ // both foo/index.ts and foo/bar.ts.
345
+ for ( const child of children ) {
346
+ const parts = child . name . split ( "/" ) ;
347
+ const collection = resolveOrCreateParents ( parts ) ;
348
+ const nav = toNavigation ( child ) ;
349
+ nav . text = parts [ parts . length - 1 ] ;
350
+ collection . push ( nav ) ;
317
351
}
318
- return reflection . comment ?. hasModifier ( "@showCategories" ) === true ;
319
- }
320
352
321
- function shouldShowGroups (
322
- reflection : Reflection ,
323
- opts : { includeCategories : boolean ; includeGroups : boolean } ,
324
- ) {
325
- if ( opts . includeGroups ) {
326
- return ! reflection . comment ?. hasModifier ( "@hideGroups" ) ;
353
+ // Now merge single-possible-paths together so we don't have folders in our navigation
354
+ // which contain only another single folder.
355
+ const queue = [ ...result ] ;
356
+ while ( queue . length ) {
357
+ const review = queue . shift ( ) ! ;
358
+ queue . push ( ...( review . children || [ ] ) ) ;
359
+ if ( review . kind || review . path ) continue ;
360
+
361
+ if ( review . children ?. length === 1 ) {
362
+ const copyFrom = review . children [ 0 ] ;
363
+ const fullName = `${ review . text } /${ copyFrom . text } ` ;
364
+ delete review . children ;
365
+ Object . assign ( review , copyFrom ) ;
366
+ review . text = fullName ;
367
+ queue . push ( review ) ;
368
+ }
327
369
}
328
- return reflection . comment ?. hasModifier ( "@showGroups" ) === true ;
370
+
371
+ return result ;
329
372
}
330
373
}
331
374
@@ -401,3 +444,17 @@ function getReflectionClasses(reflection: DeclarationReflection, filters: Record
401
444
402
445
return classes . join ( " " ) ;
403
446
}
447
+
448
+ function shouldShowCategories ( reflection : Reflection , opts : { includeCategories : boolean ; includeGroups : boolean } ) {
449
+ if ( opts . includeCategories ) {
450
+ return ! reflection . comment ?. hasModifier ( "@hideCategories" ) ;
451
+ }
452
+ return reflection . comment ?. hasModifier ( "@showCategories" ) === true ;
453
+ }
454
+
455
+ function shouldShowGroups ( reflection : Reflection , opts : { includeCategories : boolean ; includeGroups : boolean } ) {
456
+ if ( opts . includeGroups ) {
457
+ return ! reflection . comment ?. hasModifier ( "@hideGroups" ) ;
458
+ }
459
+ return reflection . comment ?. hasModifier ( "@showGroups" ) === true ;
460
+ }
0 commit comments