diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index e5e3acca117..db6c871a9b6 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -3,5 +3,7 @@ namespace PHPSTORM_META { override(\app(0), map([ 'hyde' => \Hyde\Foundation\HydeKernel::class, + 'navigation.main' => \Hyde\Framework\Features\Navigation\MainNavigationMenu::class, + 'navigation.sidebar' => \Hyde\Framework\Features\Navigation\DocumentationSidebar::class, ])); } diff --git a/packages/framework/src/Framework/Features/Navigation/DocumentationSidebar.php b/packages/framework/src/Framework/Features/Navigation/DocumentationSidebar.php index 6e8332b8ad2..a5f01904b27 100644 --- a/packages/framework/src/Framework/Features/Navigation/DocumentationSidebar.php +++ b/packages/framework/src/Framework/Features/Navigation/DocumentationSidebar.php @@ -29,11 +29,12 @@ public function __construct(Arrayable|array $items = []) public function getHeader(): string { - return Config::get('docs.sidebar.header', 'Documentation'); + return Config::getString('docs.sidebar.header', 'Documentation'); } public function getFooter(): ?string { + /** @var null|string|false $option */ $option = Config::get('docs.sidebar.footer', '[Back to home page](../)'); if (is_string($option)) { @@ -76,9 +77,12 @@ public function getActiveGroup(): ?NavigationGroup return $this->items->sortBy(fn (NavigationGroup $item): int => $item->getPriority())->first(); } - return $this->items->first(function (NavigationGroup $group) use ($currentPage): bool { + /** @var ?NavigationGroup $first */ + $first = $this->items->first(function (NavigationGroup $group) use ($currentPage): bool { // A group is active when it contains the current page being rendered. return $currentPage->navigationMenuGroup() && $group->getGroupKey() === NavigationGroup::normalizeGroupKey($currentPage->navigationMenuGroup()); }); + + return $first; } } diff --git a/packages/framework/src/Framework/Features/Navigation/NavigationGroup.php b/packages/framework/src/Framework/Features/Navigation/NavigationGroup.php index 9c472b9366a..229960da009 100644 --- a/packages/framework/src/Framework/Features/Navigation/NavigationGroup.php +++ b/packages/framework/src/Framework/Features/Navigation/NavigationGroup.php @@ -44,7 +44,7 @@ public function getPriority(): int { if ($this->containsOnlyDocumentationPages()) { // For sidebar groups, we use the priority of the lowest priority child, unless the dropdown instance itself has a lower priority. - return min($this->priority, $this->getItems()->min(fn (NavigationItem $item): int => $item->getPriority())); + return (int) min($this->priority, $this->getItems()->min(fn (NavigationItem $item): int => $item->getPriority())); } return $this->priority; diff --git a/packages/framework/src/Framework/Features/Navigation/NavigationMenu.php b/packages/framework/src/Framework/Features/Navigation/NavigationMenu.php index 7329b6bfbe9..35c48ea651e 100644 --- a/packages/framework/src/Framework/Features/Navigation/NavigationMenu.php +++ b/packages/framework/src/Framework/Features/Navigation/NavigationMenu.php @@ -17,20 +17,26 @@ * * @example `$menu = app('navigation.main');` for the main navigation menu. * @example `$menu = app('navigation.sidebar');` for the documentation sidebar. + * + * @template T of NavigationItem|NavigationGroup */ class NavigationMenu { public const DEFAULT = 500; public const LAST = 999; - /** @var \Illuminate\Support\Collection<\Hyde\Framework\Features\Navigation\NavigationItem|\Hyde\Framework\Features\Navigation\NavigationGroup> */ + /** @var \Illuminate\Support\Collection */ protected Collection $items; + /** @param \Illuminate\Contracts\Support\Arrayable|array $items */ public function __construct(Arrayable|array $items = []) { $this->items = new Collection(); - $this->add(evaluate_arrayable($items)); + /** @var array $items */ + $items = evaluate_arrayable($items); + + $this->add($items); } /** @@ -38,7 +44,7 @@ public function __construct(Arrayable|array $items = []) * * Items are automatically sorted by their priority, falling back to the order they were added. * - * @return \Illuminate\Support\Collection<\Hyde\Framework\Features\Navigation\NavigationItem|\Hyde\Framework\Features\Navigation\NavigationGroup> + * @return \Illuminate\Support\Collection */ public function getItems(): Collection { @@ -52,10 +58,11 @@ public function getItems(): Collection /** * Add one or more navigation items to the navigation menu. * - * @param \Hyde\Framework\Features\Navigation\NavigationItem|\Hyde\Framework\Features\Navigation\NavigationGroup|array<\Hyde\Framework\Features\Navigation\NavigationItem|\Hyde\Framework\Features\Navigation\NavigationGroup> $items + * @param T|array $items */ public function add(NavigationItem|NavigationGroup|array $items): static { + /** @var T $item */ foreach (Arr::wrap($items) as $item) { $this->addItem($item); } diff --git a/packages/framework/src/Framework/Features/Navigation/NavigationMenuGenerator.php b/packages/framework/src/Framework/Features/Navigation/NavigationMenuGenerator.php index d1476b87ac3..d2bd01921f8 100644 --- a/packages/framework/src/Framework/Features/Navigation/NavigationMenuGenerator.php +++ b/packages/framework/src/Framework/Features/Navigation/NavigationMenuGenerator.php @@ -23,7 +23,7 @@ */ class NavigationMenuGenerator { - /** @var \Illuminate\Support\Collection */ + /** @var \Illuminate\Support\Collection */ protected Collection $items; /** @var \Hyde\Foundation\Kernel\RouteCollection */ @@ -189,15 +189,20 @@ protected function normalizeGroupLabel(string $label): string protected function searchForGroupLabelInConfig(string $groupKey): ?string { - $key = $this->generatesSidebar ? 'docs.sidebar_group_labels' : 'hyde.navigation.labels'; - - return Config::getArray($key, [])[$groupKey] ?? null; + return $this->getConfigArray($this->generatesSidebar ? 'docs.sidebar_group_labels' : 'hyde.navigation.labels')[$groupKey] ?? null; } protected function searchForGroupPriorityInConfig(string $groupKey): ?int { - $key = $this->generatesSidebar ? 'docs.sidebar.order' : 'hyde.navigation.order'; + return $this->getConfigArray($this->generatesSidebar ? 'docs.sidebar.order' : 'hyde.navigation.order')[$groupKey] ?? null; + } + + /** @return array */ + protected function getConfigArray(string $key): array + { + /** @var array $array */ + $array = Config::getArray($key, []); - return Config::getArray($key, [])[$groupKey] ?? null; + return $array; } } diff --git a/packages/framework/tests/Feature/AutomaticNavigationConfigurationsTest.php b/packages/framework/tests/Feature/AutomaticNavigationConfigurationsTest.php index 5ae702cfad8..8d3ee0e380d 100644 --- a/packages/framework/tests/Feature/AutomaticNavigationConfigurationsTest.php +++ b/packages/framework/tests/Feature/AutomaticNavigationConfigurationsTest.php @@ -1327,11 +1327,6 @@ public function getState(int $index): ?TestNavigationItem return $this->state()[$index] ?? null; } - public function ddState(): void - { - dd($this->state()); - } - /** * @param array $expected The expected state format * @param bool $strict If false, missing array keys are ignored diff --git a/packages/framework/tests/Feature/NavigationMenuTest.php b/packages/framework/tests/Feature/NavigationMenuTest.php index a98931a6e41..7f6cb8b3ac7 100644 --- a/packages/framework/tests/Feature/NavigationMenuTest.php +++ b/packages/framework/tests/Feature/NavigationMenuTest.php @@ -199,6 +199,7 @@ public function testPagesInSubdirectoriesAreNotAddedToTheNavigationMenu() $this->file('_pages/foo/bar.md'); $menu = $this->createNavigationMenu(); + $expected = collect([NavigationItem::create(Routes::get('index'))]); $this->assertCount(count($expected), $menu->getItems()); @@ -212,6 +213,7 @@ public function testPagesInSubdirectoriesCanBeAddedToTheNavigationMenuWithConfig $this->file('_pages/foo/bar.md'); $menu = $this->createNavigationMenu(); + $expected = collect([ NavigationItem::create(Routes::get('index')), NavigationItem::create(Routes::get('foo/bar')), @@ -228,6 +230,7 @@ public function testPagesInSubdirectoriesAreNotAddedToTheNavigationMenuWithConfi $this->file('_pages/foo/bar.md'); $menu = $this->createNavigationMenu(); + $expected = collect([ NavigationItem::create(Routes::get('index')), NavigationGroup::create('Foo', [ @@ -245,6 +248,7 @@ public function testPagesInDropdownsDoNotGetAddedToTheMainNavigation() Routes::push((new MarkdownPage('foo'))->getRoute()); Routes::push((new MarkdownPage('bar/baz'))->getRoute()); + $menu = $this->createNavigationMenu(); $this->assertCount(3, $menu->getItems()); diff --git a/packages/framework/tests/Feature/Services/DocumentationSidebarTest.php b/packages/framework/tests/Feature/Services/DocumentationSidebarTest.php index 23954a7c14e..6ce5db7a0b2 100644 --- a/packages/framework/tests/Feature/Services/DocumentationSidebarTest.php +++ b/packages/framework/tests/Feature/Services/DocumentationSidebarTest.php @@ -140,8 +140,10 @@ public function testSidebarPrioritiesCanBeSetInBothFrontMatterAndConfig() 'third', 'second', ]); + Filesystem::touch('_docs/first.md'); Filesystem::touch('_docs/second.md'); + file_put_contents(Hyde::path('_docs/third.md'), (new ConvertsArrayToFrontMatter)->execute(['navigation.priority' => 250 + 300]) );