diff --git a/src/NavLink.php b/src/NavLink.php index b32bddbd..9b416ef2 100644 --- a/src/NavLink.php +++ b/src/NavLink.php @@ -27,19 +27,64 @@ */ final class NavLink { - private bool $active = false; - private array $attributes = []; - private bool $encodeLabel = true; - private bool $disabled = false; - private string|Stringable $label = ''; - private string|null $url = ''; - private array $urlAttributes = []; - /** * Use {@see NavLink::to()} to create an instance. */ - private function __construct() + private function __construct( + private bool $active = false, + private array $attributes = [], + private bool $encodeLabel = true, + private bool $disabled = false, + private string|Stringable $label = '', + private string|null $url = '', + private array $urlAttributes = [], + ) { + } + + /** + * Creates a {@see NavLink} instance. + * + * @param string|Stringable $label The label of the link. + * @param string|null $url The URL of the link. + * @param bool $active Whether the link is active. + * @param bool $disabled Whether the link is disabled. + * @param bool $encodeLabel Whether the label should be encoded. + * @param array $attributes The HTML attributes for the nav item. + * @param array $urlAttributes The HTML attributes for the nav item link. + * + * @throws InvalidArgumentException If the link is both active and disabled. + * + * @return self A new instance with the specified attributes. + */ + public static function to( + string|Stringable $label = '', + string|null $url = null, + bool $active = false, + bool $disabled = false, + bool $encodeLabel = true, + array $attributes = [], + array $urlAttributes = [], + ): self { + if ($active && $disabled) { + throw new InvalidArgumentException('A nav link cannot be both active and disabled.'); + } + + return new self($active, $attributes, $encodeLabel, $disabled, $label, $url, $urlAttributes); + } + + /** + * Sets the active state of the nav item. + * + * @param bool $value Whether the nav item is active. + * + * @return self A new instance with the specified active state. + */ + public function active(bool $value): self { + $new = clone $this; + $new->active = $value; + + return $new; } /** @@ -60,54 +105,80 @@ public function attributes(array $values): self } /** - * Sets the HTML attributes for the nav item link. + * Sets the disabled state of the nav item. * - * @param array $values Attribute values indexed by attribute names. + * @param bool $value Whether the nav item is disabled. * - * @return self A new instance with the specified attributes. + * @return self A new instance with the specified disabled state. + */ + public function disabled(bool $value): self + { + $new = clone $this; + $new->disabled = $value; + + return $new; + } + + /** + * Sets whether to HTML-encode the label. * - * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. + * @param bool $value Whether to encode the label. + * + * @return self New instance with the specified encode setting. */ - public function urlAttributes(array $values): self + public function encodeLabel(bool $value): self { $new = clone $this; - $new->urlAttributes = $values; + $new->encodeLabel = $value; return $new; } /** - * Creates a nav item. + * Sets the label text for the nav item. * - * @param string|Stringable $label The label of the link. - * @param string|null $url The URL of the link. - * @param bool $active Whether the link is active. - * @param bool $disabled Whether the link is disabled. + * @param string|Stringable $value The label text or Stringable object * - * @throws InvalidArgumentException If the link is both active and disabled. + * @return self New instance with the specified label text. + */ + public function label(string|Stringable $value): self + { + $new = clone $this; + $new->label = $value; + + return $new; + } + + /** + * Sets the URL for the nav item. * - * @return self A new instance with the specified attributes. + * @param string|null $value The URL or `null` for no URL. + * + * @return self New instance with the specified URL. */ - public static function to( - string|Stringable $label = '', - string|null $url = null, - bool $active = false, - bool $disabled = false, - bool $encodeLabel = true - ): self { - $navlink = new self(); + public function url(string|null $value): self + { + $new = clone $this; + $new->url = $value; - if ($active === true && $disabled === true) { - throw new InvalidArgumentException('A nav link cannot be both active and disabled.'); - } + return $new; + } - $navlink->active = $active; - $navlink->disabled = $disabled; - $navlink->encodeLabel = $encodeLabel; - $navlink->label = $label; - $navlink->url = $url; + /** + * Sets HTML attributes for the nav item link. + * + * @param array $values Attribute values indexed by attribute names. + * + * @return self New instance with the specified link attributes. + * + * @see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are rendered. + */ + public function urlAttributes(array $values): self + { + $new = clone $this; + $new->urlAttributes = $values; - return $navlink; + return $new; } /** diff --git a/tests/NavLinkTest.php b/tests/NavLinkTest.php index 2e4fbe6e..6e0c4758 100644 --- a/tests/NavLinkTest.php +++ b/tests/NavLinkTest.php @@ -18,7 +18,12 @@ public function testImmutability(): void { $navLink = NavLink::to('Home', '/', true); + $this->assertNotSame($navLink, $navLink->active(false)); $this->assertNotSame($navLink, $navLink->attributes([])); + $this->assertNotSame($navLink, $navLink->disabled(false)); + $this->assertNotSame($navLink, $navLink->encodeLabel(false)); + $this->assertNotSame($navLink, $navLink->label('')); + $this->assertNotSame($navLink, $navLink->url('')); $this->assertNotSame($navLink, $navLink->urlAttributes([])); } diff --git a/tests/NavTest.php b/tests/NavTest.php index b470ff02..bd71e234 100644 --- a/tests/NavTest.php +++ b/tests/NavTest.php @@ -649,7 +649,7 @@ public function testNavLinkWithAttributes(): void HTML, Nav::widget() - ->items(NavLink::to('Active', '#', active: true)->attributes(['data-test' => 'test'])) + ->items(NavLink::to('Active', '#', active: true, attributes: ['data-test' => 'test'])) ->render(), ); } @@ -665,7 +665,7 @@ public function testNavLinkWithUrlAttributes(): void HTML, Nav::widget() - ->items(NavLink::to('Active', '#', active: true)->urlAttributes(['data-test' => 'test'])) + ->items(NavLink::to('Active', '#', active: true, urlAttributes: ['data-test' => 'test'])) ->render(), ); }