Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions src/Forms/EmailInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);

namespace Eightfold\HtmlBuilder\Forms;

use Stringable;

use Eightfold\HtmlBuilder\Element;
use Eightfold\HtmlBuilder\PropertyInterface;

class EmailInput implements Stringable
{
// phpcs:disable
private string $warningId {
get => $this->name . '-warning';
}
// phpcs:enable

/**
* @var string[]
*/
private array $labelProperties = [];

/**
* @var string[]
*/
private array $inputProperties = [];

public static function create(
string|Stringable $label,
string|Stringable $name,
string $value = '',
string|PropertyInterface $warningMessage = ''
): self {
return new self($label, $name, $value, $warningMessage);
}

final private function __construct(
private readonly string|Stringable $label,
private readonly string|Stringable $name,
private readonly string $value,
private readonly string|PropertyInterface $warningMessage = ''
) {
}

public function labelProps(string ...$properties): self
{
$this->labelProperties = $properties;
return $this;
}

public function inputProps(string ...$properties): self
{
$this->inputProperties = $properties;
return $this;
}

private function warningMessage(): string|PropertyInterface
{
if ($this->warningMessage === '') {
return '';
}

if (is_string($this->warningMessage)) {
return Element::p($this->warningMessage)->props(
'id ' . $this->warningId
);
}

return $this->warningMessage->prop('id ' . $this->warningId);
}

public function __toString(): string
{
$elements = [];
$elements[] = Element::label($this->label)->props(
'for ' . $this->name,
...$this->labelProperties
);

$input = Element::input()->omitEndTag()->props(
'type email',
'id ' . $this->name,
'name ' . $this->name,
'value ' . $this->value,
...$this->inputProperties
);

$warningMessage = self::warningMessage();
$hasWarningMessage = ($warningMessage !== '');
if ($hasWarningMessage) {
$input = $input->prop('aria-invalid true');
$input = $input->prop('aria-describedby ' . $this->warningId);
}
$elements[] = $input;

if ($hasWarningMessage) {
$elements[] = $warningMessage;
}

return implode('', array_map('strval', $elements));
}
}
124 changes: 124 additions & 0 deletions src/Forms/Password.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php
declare(strict_types=1);

namespace Eightfold\HtmlBuilder\Forms;

use Stringable;

use Eightfold\HtmlBuilder\Element;
use Eightfold\HtmlBuilder\PropertyInterface;

use Eightfold\HtmlBuilder\Forms\PasswordAutocomplete;

class Password implements Stringable
{
// phpcs:disable
private string $warningId {
get => $this->name . '-warning';
}
// phpcs:enable

/**
* @var string[]
*/
private array $labelProperties = [];

/**
* @var string[]
*/
private array $inputProperties = [];


private PasswordAutocomplete $autocomplete = PasswordAutocomplete::CurrentPassword;

public static function create(
string|Stringable $label,
string|Stringable $name,
string|PropertyInterface $warningMessage = ''
): self {
return new self($label, $name, $warningMessage);
}

final private function __construct(
private readonly string|Stringable $label,
private readonly string|Stringable $name,
private readonly string|PropertyInterface $warningMessage = ''
) {
}

public function labelProps(string ...$properties): self
{
$this->labelProperties = $properties;
return $this;
}

public function inputProps(string ...$properties): self
{
$this->inputProperties = $properties;
return $this;
}

public function forNewPassword(): self
{
$this->autocomplete = PasswordAutocomplete::NewPassword;
return $this;
}

public function autocompleteOff(): self
{
$this->autocomplete = PasswordAutocomplete::Off;
return $this;
}

public function autocompleteOn(): self
{
$this->autocomplete = PasswordAutocomplete::On;
return $this;
}

private function warningMessage(): string|PropertyInterface
{
if ($this->warningMessage === '') {
return '';
}

if (is_string($this->warningMessage)) {
return Element::p($this->warningMessage)->props(
'id ' . $this->warningId
);
}

return $this->warningMessage->prop('id ' . $this->warningId);
}

public function __toString(): string
{
$elements = [];
$elements[] = Element::label($this->label)->props(
'for ' . $this->name,
...$this->labelProperties
);

$input = Element::input()->omitEndTag()->props(
'type password',
'id ' . $this->name,
'name ' . $this->name,
'autocomplete ' . $this->autocomplete->value,
...$this->inputProperties
);

$warningMessage = self::warningMessage();
$hasWarningMessage = ($warningMessage !== '');
if ($hasWarningMessage) {
$input = $input->prop('aria-invalid true');
$input = $input->prop('aria-describedby ' . $this->warningId);
}
$elements[] = $input;

if ($hasWarningMessage) {
$elements[] = $warningMessage;
}

return implode('', array_map('strval', $elements));
}
}
19 changes: 19 additions & 0 deletions src/Forms/PasswordAutocomplete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);

namespace Eightfold\HtmlBuilder\Forms;

use Stringable;

use Eightfold\HtmlBuilder\Element;
use Eightfold\HtmlBuilder\PropertyInterface;

use Eightfold\HtmlBuilder\Forms\SelectType;

enum PasswordAutocomplete: string
{
case On = 'on';
case Off = 'off';
case CurrentPassword = 'current-password';
case NewPassword = 'new-password';
}
12 changes: 8 additions & 4 deletions src/Forms/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ private function selectDropdown(): Element
{
$elements = [];

$hasWarningMessage = (self::warningMessage() !== '');
$warningMessage = self::warningMessage();
$hasWarningMessage = ($warningMessage !== '');

foreach ($this->options as $value => $content) {
$value = (string) $value;
$option = Element::option($content)->props('value ' . $value);
Expand All @@ -180,7 +182,7 @@ private function selectDropdown(): Element
$this->label
)->props('for ' . $this->name, ...$this->labelProperties),
$input,
self::warningMessage()
$warningMessage
)->props(...$this->wrapperProperties);
}

Expand All @@ -189,7 +191,9 @@ private function selectOther(): Element
$elements = [];
$type = $this->type === SelectType::Checkbox ? 'checkbox' : 'radio';

$hasWarningMessage = (self::warningMessage() !== '');
$warningMessage = self::warningMessage();
$hasWarningMessage = ($warningMessage !== '');

foreach ($this->options as $value => $content) {
$value = (string) $value;
$id = $this->name . '-' . $value;
Expand All @@ -215,7 +219,7 @@ private function selectOther(): Element
}

if ($hasWarningMessage) {
$elements[] = self::warningMessage();
$elements[] = $warningMessage;
}

return Element::fieldset(
Expand Down
103 changes: 103 additions & 0 deletions src/Forms/TextInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);

namespace Eightfold\HtmlBuilder\Forms;

use Stringable;

use Eightfold\HtmlBuilder\Element;
use Eightfold\HtmlBuilder\PropertyInterface;

class TextInput implements Stringable
{
// phpcs:disable
private string $warningId {
get => $this->name . '-warning';
}
// phpcs:enable

/**
* @var string[]
*/
private array $labelProperties = [];

/**
* @var string[]
*/
private array $inputProperties = [];

public static function create(
string|Stringable $label,
string|Stringable $name,
string $value = '',
string|PropertyInterface $warningMessage = ''
): self {
return new self($label, $name, $value, $warningMessage);
}

final private function __construct(
private readonly string|Stringable $label,
private readonly string|Stringable $name,
private readonly string $value,
private readonly string|PropertyInterface $warningMessage = ''
) {
}

public function labelProps(string ...$properties): self
{
$this->labelProperties = $properties;
return $this;
}

public function inputProps(string ...$properties): self
{
$this->inputProperties = $properties;
return $this;
}

private function warningMessage(): string|PropertyInterface
{
if ($this->warningMessage === '') {
return '';
}

if (is_string($this->warningMessage)) {
return Element::p($this->warningMessage)->props(
'id ' . $this->warningId
);
}

return $this->warningMessage->prop('id ' . $this->warningId);
}

public function __toString(): string
{
$elements = [];
$elements[] = Element::label($this->label)->props(
'for ' . $this->name,
...$this->labelProperties
);

$input = Element::input()->omitEndTag()->props(
'type text',
'id ' . $this->name,
'name ' . $this->name,
'value ' . $this->value,
...$this->inputProperties
);

$warningMessage = self::warningMessage();
$hasWarningMessage = ($warningMessage !== '');
if ($hasWarningMessage) {
$input = $input->prop('aria-invalid true');
$input = $input->prop('aria-describedby ' . $this->warningId);
}
$elements[] = $input;

if ($hasWarningMessage) {
$elements[] = $warningMessage;
}

return implode('', array_map('strval', $elements));
}
}
Loading
Loading