diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f9e7e..9c4716f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 4.2.1 under development -- no changes in this release. +- New #279: Add support for conditional CSS classes in `Html::addCssClass()` (@Mister-42) ## 4.2.0 June 05, 2026 diff --git a/src/Html.php b/src/Html.php index 481b9cd..43ce093 100644 --- a/src/Html.php +++ b/src/Html.php @@ -1706,10 +1706,10 @@ public static function renderTagAttributes(array $attributes): string * * @param array $attributes The attributes to be modified. All string values in the array must be valid UTF-8 * strings. - * @param BackedEnum|BackedEnum[]|null[]|string|string[]|null $class The CSS class(es) to be added. Null values will - * be ignored. + * @param (BackedEnum|null|bool|string)[]|BackedEnum|string|null $class The CSS class(es) to be added. Null values will + * be ignored. When passing an array, use a boolean value to conditionally include/exclude a class by its key. * - * @psalm-param BackedEnum|string|array|null $class + * @psalm-param BackedEnum|string|array|null $class */ public static function addCssClass(array &$attributes, BackedEnum|array|string|null $class): void { @@ -1727,6 +1727,13 @@ public static function addCssClass(array &$attributes, BackedEnum|array|string|n if (is_array($class)) { $filteredClass = []; foreach ($class as $key => $value) { + if (is_bool($value)) { + if ($value && is_string($key)) { + $filteredClass[] = $key; + } + continue; + } + if ($value instanceof BackedEnum) { $value = is_string($value->value) ? $value->value : null; } diff --git a/tests/HtmlTest.php b/tests/HtmlTest.php index eaf0ffd..572cef2 100644 --- a/tests/HtmlTest.php +++ b/tests/HtmlTest.php @@ -1049,6 +1049,15 @@ public static function dataAddCssClass(): array 16 => [['id' => 'w2', 'class' => 't1'], ['id' => 'w2'], 't1'], 17 => [['id' => 'w2', 'class' => ['t3', 2 => 't4']], ['id' => 'w2'], ['t3', null, 't4']], 18 => [['id' => 'w2', 'class' => ['t3', 2 => 't4']], ['id' => 'w2'], ['t3', null, 't4', null]], + 19 => [['class' => ['btn-active']], [], ['btn-active' => true]], + 20 => [[], [], ['btn-active' => false]], + 21 => [['class' => ['btn', 'btn-active']], [], ['btn', 'btn-active' => true]], + 22 => [['class' => ['btn']], [], ['btn', 'btn-active' => false]], + 23 => [['class' => ['btn', 'btn-active']], ['class' => 'btn'], ['btn-active' => true]], + 24 => [['class' => 'btn'], ['class' => 'btn'], ['btn-active' => false]], + 25 => [['class' => ['btn', 'btn-active']], ['class' => 'btn'], ['btn-active' => true, 'hidden' => false]], + 26 => [['class' => ['btn']], ['class' => 'btn'], ['btn' => true]], + 27 => [['class' => ['persistent' => 'widget', 'btn', 'btn-active']], ['class' => ['persistent' => 'widget']], ['btn', 'btn-active' => true]], ]; }