diff --git a/src/Framework/Features/Navigation/NavigationMenu.php b/src/Framework/Features/Navigation/NavigationMenu.php index bcc844dc..adf939a7 100644 --- a/src/Framework/Features/Navigation/NavigationMenu.php +++ b/src/Framework/Features/Navigation/NavigationMenu.php @@ -11,6 +11,8 @@ class NavigationMenu extends BaseNavigationMenu { + private bool $hasDropdowns; + protected function generate(): void { parent::generate(); @@ -69,6 +71,13 @@ protected function canAddItemToDropdown(NavItem $item): bool protected function dropdownsEnabled(): bool { - return Config::getString('hyde.navigation.subdirectories', 'hidden') === 'dropdown'; + return (Config::getString('hyde.navigation.subdirectories', 'hidden') === 'dropdown') || $this->hasGroupExplicitlySetInFrontMatter(); + } + + private function hasGroupExplicitlySetInFrontMatter(): bool + { + return $this->hasDropdowns ??= $this->items->contains(function (NavItem $item): bool { + return ($item->getGroup() !== null) && ($item->destination !== (string) DocumentationPage::home()); + }); } } diff --git a/tests/Feature/NavigationMenuTest.php b/tests/Feature/NavigationMenuTest.php index a36346e4..64450a9b 100644 --- a/tests/Feature/NavigationMenuTest.php +++ b/tests/Feature/NavigationMenuTest.php @@ -383,4 +383,38 @@ public function testDropdownMenuItemsAreSortedByPriority() $this->assertSame(['Foo', 'Bar', 'Baz'], $dropdowns[0]->getItems()->pluck('label')->toArray()); } + + public function testHasDropdownsReturnsTrueWhenGroupIsExplicitlySetInFrontMatter() + { + config(['hyde.navigation.subdirectories' => 'hidden']); + + Routes::addRoute((new MarkdownPage('foo', matter: ['navigation.group' => 'test-group']))->getRoute()); + + $this->assertTrue(NavigationMenu::create()->hasDropdowns()); + } + + public function testGetDropdownsReturnsCorrectArrayWhenGroupIsExplicitlySetInFrontMatter() + { + config(['hyde.navigation.subdirectories' => 'hidden']); + + Routes::addRoute((new MarkdownPage('foo', matter: ['navigation.group' => 'test-group']))->getRoute()); + + $menu = NavigationMenu::create(); + $this->assertCount(1, $menu->getDropdowns()); + + $this->assertEquals([ + DropdownNavItem::fromArray('test-group', [ + NavItem::fromRoute((new MarkdownPage('foo'))->getRoute()), + ]), + ], $menu->getDropdowns()); + } + + public function testHasDropdownsReturnsFalseWhenGroupIsNotExplicitlySetInFrontMatter() + { + config(['hyde.navigation.subdirectories' => 'hidden']); + + Routes::addRoute((new MarkdownPage('foo'))->getRoute()); + $menu = NavigationMenu::create(); + $this->assertFalse($menu->hasDropdowns()); + } } diff --git a/tests/Unit/NavigationDataFactoryUnitTest.php b/tests/Unit/NavigationDataFactoryUnitTest.php index a118c695..8074f2ef 100644 --- a/tests/Unit/NavigationDataFactoryUnitTest.php +++ b/tests/Unit/NavigationDataFactoryUnitTest.php @@ -146,6 +146,36 @@ public function testRouteKeysCanBeUsedForDocumentationSidebarPriorities() $this->assertSame(502, $factory->makePriority()); } + public function testMakeGroupUsesFrontMatterGroupIfSet() + { + $frontMatter = new FrontMatter(['navigation.group' => 'Test Group']); + $coreDataObject = new CoreDataObject($frontMatter, new Markdown(), MarkdownPage::class, 'test.md', '', '', ''); + $factory = new NavigationConfigTestClass($coreDataObject); + + $this->assertSame('Test Group', $factory->makeGroup()); + } + + public function testMakeGroupUsesFrontMatterGroupIfSetRegardlessOfSubdirectoryConfiguration() + { + self::mockConfig(['hyde.navigation.subdirectories' => 'hidden']); + + $frontMatter = new FrontMatter(['navigation.group' => 'Test Group']); + $coreDataObject = new CoreDataObject($frontMatter, new Markdown(), MarkdownPage::class, 'test.md', '', '', ''); + $factory = new NavigationConfigTestClass($coreDataObject); + + $this->assertSame('Test Group', $factory->makeGroup()); + } + + public function testMakeGroupDefaultsToNullIfFrontMatterGroupNotSetAndSubdirectoriesNotUsed() + { + self::mockConfig(['hyde.navigation.subdirectories' => 'hidden']); + + $coreDataObject = new CoreDataObject(new FrontMatter(), new Markdown(), MarkdownPage::class, 'test.md', '', '', ''); + $factory = new NavigationConfigTestClass($coreDataObject); + + $this->assertNull($factory->makeGroup()); + } + protected function makeCoreDataObject(string $identifier = '', string $routeKey = '', string $pageClass = MarkdownPage::class): CoreDataObject { return new CoreDataObject(new FrontMatter(), new Markdown(), $pageClass, $identifier, '', '', $routeKey); @@ -163,4 +193,9 @@ public function makePriority(): int { return parent::makePriority(); } + + public function makeGroup(): ?string + { + return parent::makeGroup(); + } }