From b504e0c162a3eea38e63f010a99a289ddc3a8fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Alejandro=20L=C3=B3pez=20L=C3=B3pez?= Date: Mon, 9 Sep 2024 13:33:35 -0400 Subject: [PATCH] Fix #14: Use `ul` and `li` tags for the default layout of the `ListView` --- src/ListView.php | 85 +++++++++++-- tests/ListView/BaseTest.php | 212 +++++++++++++++++++++++++++---- tests/ListView/ExceptionTest.php | 22 ++++ 3 files changed, 281 insertions(+), 38 deletions(-) diff --git a/src/ListView.php b/src/ListView.php index d510759de..0e4881fc9 100644 --- a/src/ListView.php +++ b/src/ListView.php @@ -6,7 +6,7 @@ use Closure; use InvalidArgumentException; -use Yiisoft\Html\Tag\Div; +use Yiisoft\Html\Html; use Yiisoft\View\Exception\ViewNotFoundException; use Yiisoft\View\View; @@ -20,11 +20,21 @@ final class ListView extends BaseListView private ?Closure $afterItem = null; private ?Closure $beforeItem = null; + /** + * @psalm-var non-empty-string|null + */ + private ?string $itemsWrapperTag = 'ul'; + private array $itemsWrapperAttributes = []; + /** * @var callable|string|null */ private $itemView = null; + /** + * @psalm-var non-empty-string|null + */ + private ?string $itemViewTag = 'li'; private array $itemViewAttributes = []; private string $separator = "\n"; private array $viewParams = []; @@ -81,6 +91,36 @@ public function beforeItem(Closure $value): self return $new; } + /** + * Set the HTML tag for the items wrapper. + * + * @param string|null $tag + * @return $this + */ + public function itemsWrapperTag(?string $tag): self + { + if ($tag === '') { + throw new InvalidArgumentException('The "itemsWrapperTag" property cannot be empty.'); + } + + $new = clone $this; + $new->itemsWrapperTag = $tag; + return $new; + } + + /** + * Set the HTML attributes for the container of the items wrapper. + * + * @param array $values + * @return $this + */ + public function itemsWrapperAttributes(array $values): self + { + $new = clone $this; + $new->itemsWrapperAttributes = $values; + return $new; + } + /** * Return new instance with itemView closure. * @@ -108,6 +148,23 @@ public function itemView(string|Closure $value): self return $new; } + /** + * Set the HTML tag for the container of item view. + * + * @param string|null $tag + * @return $this + */ + public function itemViewTag(?string $tag): self + { + if ($tag === '') { + throw new InvalidArgumentException('The "itemViewTag" property cannot be empty.'); + } + + $new = clone $this; + $new->itemViewTag = $tag; + return $new; + } + /** * return new instance with the HTML attributes for the container of item view. * @@ -182,14 +239,16 @@ protected function renderItem(array|object $data, mixed $key, int $index): strin } if ($this->itemView instanceof Closure) { - $content = (string) call_user_func($this->itemView, $data, $key, $index, $this); + $content = (string)call_user_func($this->itemView, $data, $key, $index, $this); } - return Div::tag() - ->attributes($this->itemViewAttributes) - ->content("\n" . $content) - ->encode(false) - ->render(); + return $this->itemViewTag === null + ? $content + : Html::tag($this->itemViewTag) + ->attributes($this->itemViewAttributes) + ->content("\n" . $content) + ->encode(false) + ->render(); } /** @@ -217,7 +276,13 @@ protected function renderItems(array $items, \Yiisoft\Validator\Result $filterVa } } - return implode($this->separator, $rows); + $content = implode($this->separator, $rows); + + return $this->itemsWrapperTag === null + ? $content + : Html::tag($this->itemsWrapperTag, "\n" . $content . "\n", $this->itemsWrapperAttributes) + ->encode(false) + ->render(); } /** @@ -238,7 +303,7 @@ private function renderAfterItem(array|object $data, mixed $key, int $index): st $result = ''; if (!empty($this->afterItem)) { - $result = (string) call_user_func($this->afterItem, $data, $key, $index, $this); + $result = (string)call_user_func($this->afterItem, $data, $key, $index, $this); } return $result; @@ -262,7 +327,7 @@ private function renderBeforeItem(array|object $data, mixed $key, int $index): s $result = ''; if (!empty($this->beforeItem)) { - $result = (string) call_user_func($this->beforeItem, $data, $key, $index, $this); + $result = (string)call_user_func($this->beforeItem, $data, $key, $index, $this); } return $result; diff --git a/tests/ListView/BaseTest.php b/tests/ListView/BaseTest.php index c1c22e2c9..69f9bd695 100644 --- a/tests/ListView/BaseTest.php +++ b/tests/ListView/BaseTest.php @@ -27,16 +27,18 @@ public function testAfterItemBeforeItem(): void Assert::equalsWithoutLE( << +
Page 1 of 1
HTML, @@ -54,12 +56,14 @@ public function testItemViewAttributes(): void Assert::equalsWithoutLE( << -
+
-
+ +
  • Id: 2
    Name: Mary
    Age: 21
    -
  • + +
    Page 1 of 1
    HTML, @@ -76,12 +80,14 @@ public function testItemViewAsString(): void Assert::equalsWithoutLE( << -
    +
    -
    + +
  • Id: 2
    Name: Mary
    Age: 21
    -
  • + +
    Page 1 of 1
    HTML, @@ -103,12 +109,14 @@ public function testItemViewAsCallable(): void Assert::equalsWithoutLE( << -
    +
    -
    + +
  • 2
    Mary
    -
  • + +
    Page 1 of 1
    HTML, @@ -132,12 +140,14 @@ public function testSeparator(): void Assert::equalsWithoutLE( << -
    +
    -
    + +
  • Id: 2
    Name: Mary
    Age: 21
    -
  • + +
    Page 1 of 1
    HTML, @@ -160,12 +170,14 @@ public function testViewParams(): void Assert::equalsWithoutLE( << -
    +
    -
    + +
  • 2
    -
  • + +
    Page 1 of 1
    HTML, @@ -183,9 +195,11 @@ public function testOffsetPaginationConfig(): void Assert::equalsWithoutLE( << -
    +
    + +
    Page 1 of 2