diff --git a/.changeset/fluffy-jeans-approve.md b/.changeset/fluffy-jeans-approve.md new file mode 100644 index 000000000..cb8b774aa --- /dev/null +++ b/.changeset/fluffy-jeans-approve.md @@ -0,0 +1,5 @@ +--- +'typedoc-plugin-markdown': patch +--- + +- Correctly handle top level custom groups in navigation (#685) diff --git a/devtools/packages/fixtures/typedoc.cjs b/devtools/packages/fixtures/typedoc.cjs index a01312618..063735a2c 100644 --- a/devtools/packages/fixtures/typedoc.cjs +++ b/devtools/packages/fixtures/typedoc.cjs @@ -12,9 +12,6 @@ module.exports = { URL: 'https://developer.mozilla.org/en-US/docs/Web/API/URL', }, }, - navigation: { - includeGroups: true, - }, locales: { en: { theme_defined_in: 'Source', diff --git a/packages/typedoc-plugin-markdown/src/theme/base/navigation-builder.ts b/packages/typedoc-plugin-markdown/src/theme/base/navigation-builder.ts index e31011a05..fa61de574 100644 --- a/packages/typedoc-plugin-markdown/src/theme/base/navigation-builder.ts +++ b/packages/typedoc-plugin-markdown/src/theme/base/navigation-builder.ts @@ -17,7 +17,11 @@ import { export class NavigationBuilder { private options: Options; private packagesMeta: any; - private navigationOptions: any; + private navigationOptions: { + excludeCategories: boolean; + excludeGroups: boolean; + excludeFolders: boolean; + }; private navigation: NavigationItem[] = []; private isPackages: boolean; @@ -26,7 +30,7 @@ export class NavigationBuilder { public project: ProjectReflection, ) { this.options = theme.application.options; - this.navigationOptions = this.options.getValue('navigationModel'); + this.navigationOptions = this.getNavigationOptions(); this.packagesMeta = ( theme.application.renderer as unknown as MarkdownRenderer ).packagesMeta; @@ -54,6 +58,18 @@ export class NavigationBuilder { return this.navigation; } + private getNavigationOptions() { + if (this.options.isSet('navigation')) { + const navigationOptions = this.options.getValue('navigation'); + return { + excludeCategories: !navigationOptions.includeCategories, + excludeGroups: !navigationOptions.includeGroups, + excludeFolders: !navigationOptions.includeFolders, + }; + } + return this.options.getValue('navigationModel'); + } + private removeEmptyChildren(navigation: NavigationItem[]): void { navigation.forEach((navItem) => { if (navItem.children) { @@ -153,24 +169,46 @@ export class NavigationBuilder { ); if (isOnlyModules) { project.groups?.forEach((projectGroup) => { - if (projectGroup.owningReflection.kind === ReflectionKind.Module) { - const children = this.getGroupChildren(projectGroup); + const children = this.getGroupChildren(projectGroup); + if ( + projectGroup.title === + this.theme.application.internationalization.proxy.kind_plural_module() + ) { if (children?.length) { this.navigation.push( ...children.filter((child) => child.title !== entryModule), ); } } else { - this.navigation.push({ - title: projectGroup.title, - children: projectGroup.children.map((child) => { - return { - title: child.name, - kind: child.kind, - path: child.url, - }; - }), - }); + if (this.navigationOptions.excludeGroups) { + if (children?.length) { + this.navigation.push( + ...children.filter((child) => child.title !== entryModule), + ); + } + } else { + if ( + projectGroup.owningReflection.kind === ReflectionKind.Document + ) { + this.navigation.push({ + title: projectGroup.title, + children: projectGroup.children.map((child) => { + return { + title: child.name, + kind: child.kind, + path: child.url, + }; + }), + }); + } else { + this.navigation.push({ + title: projectGroup.title, + children: children?.filter( + (child) => child.title !== entryModule, + ), + }); + } + } } }); } else { diff --git a/packages/typedoc-plugin-markdown/test/fixtures/config.ts b/packages/typedoc-plugin-markdown/test/fixtures/config.ts index 3064da822..abb9b2314 100644 --- a/packages/typedoc-plugin-markdown/test/fixtures/config.ts +++ b/packages/typedoc-plugin-markdown/test/fixtures/config.ts @@ -341,6 +341,36 @@ const config: Record = { }, ], }, + navigation: { + only: false, + entryPoints: [ + '/navigation/module-1/index.ts', + '/navigation/module-2/index.ts', + ], + commonOptions: { + hidePageHeader: true, + readme: 'none', + plugin: [path.join(__dirname, 'custom-plugins', 'navigation-plugin.mjs')], + }, + options: [ + { + navigation: { + includeCategories: false, + includeGroups: false, + includeFolders: false, + }, + categorizeByGroup: true, + }, + { + navigation: { + includeCategories: true, + includeGroups: true, + includeFolders: true, + }, + categorizeByGroup: false, + }, + ], + }, }; export default config; diff --git a/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-1/index.ts b/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-1/index.ts new file mode 100644 index 000000000..51cb55888 --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-1/index.ts @@ -0,0 +1,19 @@ +/** + * @group Group 1 + * @module Module1 + */ + +/** + * @category Category 1 + */ +export interface SomeInterface1 {} + +/** + * @category Category 1 + */ +export interface SomeInterface2 {} + +/** + * @category Category 2 + */ +export interface SomeInterface3 {} diff --git a/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-2/index.ts b/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-2/index.ts new file mode 100644 index 000000000..db2a103b6 --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/fixtures/src/navigation/module-2/index.ts @@ -0,0 +1,6 @@ +/** + * @group Group 2 + * @module Module2 + */ + +export interface SomeInterface {} diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/navigation.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/navigation.spec.ts.snap index 0aed462d5..dd79f58c3 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/navigation.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/navigation.spec.ts.snap @@ -963,6 +963,149 @@ exports[`Navigation should get Navigation Json for packages: (Output File Strate ]" `; +exports[`Navigation should get with and without groups and categories: (Output File Strategy "members") (Option Group "1") 1`] = ` +"[ + { + "title": "Module1", + "kind": 2, + "path": "Module1/README.md", + "children": [ + { + "title": "SomeInterface1", + "kind": 256, + "path": "Module1/interfaces/SomeInterface1.md" + }, + { + "title": "SomeInterface2", + "kind": 256, + "path": "Module1/interfaces/SomeInterface2.md" + }, + { + "title": "SomeInterface3", + "kind": 256, + "path": "Module1/interfaces/SomeInterface3.md" + } + ] + }, + { + "title": "Module2", + "kind": 2, + "path": "Module2/README.md", + "children": [ + { + "title": "SomeInterface", + "kind": 256, + "path": "Module2/interfaces/SomeInterface.md" + } + ] + } +]" +`; + +exports[`Navigation should get with and without groups and categories: (Output File Strategy "members") (Option Group "2") 1`] = ` +"[ + { + "title": "Group 1", + "children": [ + { + "title": "Module1", + "kind": 2, + "path": "Module1/README.md", + "children": [ + { + "title": "Category 1", + "children": [ + { + "title": "SomeInterface1", + "kind": 256, + "path": "Module1/interfaces/SomeInterface1.md" + }, + { + "title": "SomeInterface2", + "kind": 256, + "path": "Module1/interfaces/SomeInterface2.md" + } + ] + }, + { + "title": "Category 2", + "children": [ + { + "title": "SomeInterface3", + "kind": 256, + "path": "Module1/interfaces/SomeInterface3.md" + } + ] + } + ] + } + ] + }, + { + "title": "Group 2", + "children": [ + { + "title": "Module2", + "kind": 2, + "path": "Module2/README.md", + "children": [ + { + "title": "Interfaces", + "children": [ + { + "title": "SomeInterface", + "kind": 256, + "path": "Module2/interfaces/SomeInterface.md" + } + ] + } + ] + } + ] + } +]" +`; + +exports[`Navigation should get with and without groups and categories: (Output File Strategy "modules") (Option Group "1") 1`] = ` +"[ + { + "title": "Module1", + "kind": 2, + "path": "Module1.md" + }, + { + "title": "Module2", + "kind": 2, + "path": "Module2.md" + } +]" +`; + +exports[`Navigation should get with and without groups and categories: (Output File Strategy "modules") (Option Group "2") 1`] = ` +"[ + { + "title": "Group 1", + "children": [ + { + "title": "Module1", + "kind": 2, + "path": "Module1.md" + } + ] + }, + { + "title": "Group 2", + "children": [ + { + "title": "Module2", + "kind": 2, + "path": "Module2.md" + } + ] + } +]" +`; + exports[`Navigation should gets Navigation Json for documents multi module: (Output File Strategy "members") (Option Group "1") 1`] = ` "[ { diff --git a/packages/typedoc-plugin-markdown/test/specs/navigation.spec.ts b/packages/typedoc-plugin-markdown/test/specs/navigation.spec.ts index 59811015d..0407ebf91 100644 --- a/packages/typedoc-plugin-markdown/test/specs/navigation.spec.ts +++ b/packages/typedoc-plugin-markdown/test/specs/navigation.spec.ts @@ -1,6 +1,10 @@ import { expectFileToEqual } from '@devtools/testing'; describe(`Navigation`, () => { + test(`should get with and without groups and categories`, () => { + expectFileToEqual('navigation', ['members', 'modules'], 'sidebar.json'); + }); + test(`should gets Navigation Json for single entry point`, () => { expectFileToEqual('reflections', ['members', 'modules'], 'sidebar.json', 1); });