From c5e48ff9039d5c743be4b1076a2f18717a39271a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 16:55:21 +0000 Subject: [PATCH 1/3] Initial plan From 6a03bb35a9bde1c5cae7841c16c6164838b52fd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:46:22 +0000 Subject: [PATCH 2/3] Re-add activateParents feature to Nav widget Co-authored-by: samdark <47294+samdark@users.noreply.github.com> --- src/Nav.php | 50 +++++++++++++++++++- tests/NavTest.php | 115 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/src/Nav.php b/src/Nav.php index b2155ce5..fc471dfb 100644 --- a/src/Nav.php +++ b/src/Nav.php @@ -62,6 +62,8 @@ final class Nav extends Widget private bool $activateItems = true; + private bool $activateParents = false; + private array $attributes = []; private array $cssClasses = []; @@ -103,6 +105,29 @@ public function activateItems(bool $enabled): self return $new; } + /** + * Whether to activate the parent dropdown item when one of its child items is active. + * + * When set to `true`, if a dropdown item's URL matches {@see currentPath}, the dropdown toggle (parent) will also + * receive the `active` CSS class. + * + * @param bool $enabled Whether to activate parent items. Defaults to `false`. + * + * @return self A new instance with the specified activate parents value. + * + * Example usage: + * ```php + * $nav->activateParents(true); + * ``` + */ + public function activateParents(bool $enabled): self + { + $new = clone $this; + $new->activateParents = $enabled; + + return $new; + } + /** * Adds a set of attributes. * @@ -591,6 +616,24 @@ private function isTabsOrPills(): bool || in_array(NavStyle::PILLS, $this->styleClasses, true); } + /** + * Checks whether any item in the dropdown is active. + * + * @param Dropdown $dropdown The dropdown to check. + * + * @return bool Whether any item in the dropdown is active. + */ + private function hasActiveDropdownItem(Dropdown $dropdown): bool + { + foreach ($dropdown->getItems() as $item) { + if ($item->isActive()) { + return true; + } + } + + return false; + } + /** * Renders the items for the nav component. * @@ -621,6 +664,11 @@ private function renderItems(): array private function renderItemsDropdown(Dropdown $items): Li { $dropDownItems = $this->isDropdownActive($items); + $togglerClasses = ['nav-link', 'dropdown-toggle']; + + if ($this->activateParents && $this->hasActiveDropdownItem($dropDownItems)) { + $togglerClasses[] = self::NAV_LINK_ACTIVE_CLASS; + } return Li::tag() ->addClass(...$this->dropdownCssClasses, ...$dropDownItems->getCssClasses()) @@ -629,7 +677,7 @@ private function renderItemsDropdown(Dropdown $items): Li $dropDownItems ->container(false) ->togglerAsLink() - ->togglerClass('nav-link', 'dropdown-toggle') + ->togglerClass(...$togglerClasses) ->render(), "\n", ) diff --git a/tests/NavTest.php b/tests/NavTest.php index 6a6c3c10..719dc936 100644 --- a/tests/NavTest.php +++ b/tests/NavTest.php @@ -22,6 +22,120 @@ #[Group('nav')] final class NavTest extends TestCase { + public function testActivateParents(): void + { + Assert::equalsWithoutLE( + << +