Skip to content

Commit

Permalink
Add AbstractButtonGroup and ButtonGroup classes. (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Dec 21, 2023
1 parent 60d45ae commit 5d56c4b
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 1 deletion.
76 changes: 76 additions & 0 deletions src/Input/Base/AbstractButtonGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace PHPForge\Html\Input\Base;

use PHPForge\Html\Attribute;
use PHPForge\Html\Input\Button;
use PHPForge\Html\Tag;
use PHPForge\Widget\Element;

use function implode;

abstract class AbstractButtonGroup extends Element
{
use Attribute\Custom\HasContainer;

/**
* @psalm-var Button[]
*/
protected array $buttons = [];
protected bool $container = true;
protected string $containerTag = 'div';
protected bool $individualContainer = false;

/**
* Returns a new instance specifying List of buttons. Each array element represents a single input button.
*
* @param array $values The list of buttons.
*
* @psalm-param Button[] $values
*/
public function buttons(Button ...$values): static
{
$new = clone $this;
$new->buttons = $values;

return $new;
}

/**
* Returns a new instance specifying if each button should be wrapped in a container.
*
* @param bool $value If true, each button will be wrapped in a container.
*/
public function individualContainer(bool $value): static
{
$new = clone $this;
$new->individualContainer = $value;

return $new;
}

protected function run(): string
{
return match ($this->container) {
true => Tag::widget()
->attributes($this->containerAttributes)
->content($this->renderButtons())
->tagName($this->containerTag)
->render(),
false => $this->renderButtons(),
};
}

private function renderButtons(): string
{
$buttons = [];

foreach ($this->buttons as $button) {
$buttons[] = $button->container($this->individualContainer)->render();
}

return implode("\n", $buttons);
}
}
4 changes: 3 additions & 1 deletion src/Input/Base/AbstractHidden.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ abstract class AbstractHidden extends AbstractInput
'tabindex',
'title',
];

protected string $type = 'hidden';

protected function run(): string
{
$attributes = $this->attributes;
$value = $attributes['value'] ?? null;

foreach (static::NOT_ALLOWED_ATTRIBUTES as $attribute) {
if (array_key_exists($attribute, $attributes)) {
Expand All @@ -42,6 +42,8 @@ protected function run(): string
}
}

$value = $attributes['value'] ?? null;

/**
* @link https://www.w3.org/TR/2012/WD-html-markup-20120329/input.hidden.html#input.hidden.attrs.value
*/
Expand Down
26 changes: 26 additions & 0 deletions src/Input/ButtonGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace PHPForge\Html\Input;

/**
* ButtonGroup renders a button group widget.
*
* For example,
*
* ```php
* <?=
* ButtonGroup::create()
* ->buttons(
* Button::widget()->label('Submit')->type('submit'),
* Button::widget()->label('Reset')->type('reset')
* );
* ?>
* ```
*
* Pressing on the button should be handled via JavaScript. See the following for details:
*/
final class ButtonGroup extends Base\AbstractButtonGroup
{
}
23 changes: 23 additions & 0 deletions tests/Input/ButtonGroup/ImmutabilityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace PHPForge\Html\Tests\Input\ButtonGroup;

use PHPForge\Html\Input\Button;
use PHPForge\Html\Input\ButtonGroup;
use PHPUnit\Framework\TestCase;

/**
* @psalm-suppress PropertyNotSetInConstructor
*/
final class ImmutabilityTest extends TestCase
{
public function testImmutability(): void
{
$widget = ButtonGroup::widget();

$this->assertNotSame($widget, $widget->buttons(Button::widget()));
$this->assertNotSame($widget, $widget->individualContainer(false));
}
}
131 changes: 131 additions & 0 deletions tests/Input/ButtonGroup/RenderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

declare(strict_types=1);

namespace PHPForge\Html\Tests\Input\ButtonGroup;

use PHPForge\Html\Input\Button;
use PHPForge\Html\Input\ButtonGroup;
use PHPForge\Support\Assert;
use PHPUnit\Framework\TestCase;

/**
* @psalm-suppress PropertyNotSetInConstructor
*/
final class RenderTest extends TestCase
{
public function testContainerAttributes(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div class="class">
<input id="text-6582f2d099e8a" type="submit" value="Submit">
<input id="text-6582f2d099e8b" type="reset" value="Reset">
</div>
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->containerAttributes(['class' => 'class'])
->render()
);
}

public function testContainerClass(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div class="class">
<input id="text-6582f2d099e8a" type="submit" value="Submit">
<input id="text-6582f2d099e8b" type="reset" value="Reset">
</div>
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->containerClass('class')
->render()
);
}

public function testContainerTag(): void
{
Assert::equalsWithoutLE(
<<<HTML
<article>
<input id="text-6582f2d099e8a" type="submit" value="Submit">
<input id="text-6582f2d099e8b" type="reset" value="Reset">
</article>
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->containerTag('article')
->render()
);
}

public function testContainerWithFalse(): void
{
Assert::equalsWithoutLE(
<<<HTML
<input id="text-6582f2d099e8a" type="submit" value="Submit">
<input id="text-6582f2d099e8b" type="reset" value="Reset">
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->container(false)
->render()
);
}

public function testIndividualContainer(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div>
<div>
<input id="text-6582f2d099e8a" type="submit" value="Submit">
</div>
<div>
<input id="text-6582f2d099e8b" type="reset" value="Reset">
</div>
</div>
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->individualContainer(true)
->render()
);
}

public function testRender(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div>
<input id="text-6582f2d099e8a" type="submit" value="Submit">
<input id="text-6582f2d099e8b" type="reset" value="Reset">
</div>
HTML,
ButtonGroup::widget()
->buttons(
Button::widget()->id('text-6582f2d099e8a')->type('submit')->value('Submit'),
Button::widget()->id('text-6582f2d099e8b')->type('reset')->value('Reset')
)
->render()
);
}
}

0 comments on commit 5d56c4b

Please sign in to comment.