Skip to content

Commit

Permalink
Merge pull request #34 from tempestphp/static-components
Browse files Browse the repository at this point in the history
Static components
  • Loading branch information
brendt authored May 13, 2024
2 parents cf0b121 + 29d583a commit 34db7a6
Show file tree
Hide file tree
Showing 43 changed files with 990 additions and 146 deletions.
23 changes: 0 additions & 23 deletions src/Components/ComponentRenderer.php

This file was deleted.

10 changes: 10 additions & 0 deletions src/Components/HasStaticComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Tempest\Console\Components;

interface HasStaticComponent
{
public function getStaticComponent(): StaticComponent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticConfirmComponent;
use Tempest\Console\Components\StaticComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\HasCursor;
use Tempest\Console\HasFooter;
use Tempest\Console\Key;
use Tempest\Console\Point;

final class ConfirmComponent implements ConsoleComponent, HasFooter, HasCursor
final class ConfirmComponent implements InteractiveComponent, HasFooter, HasCursor, HasStaticComponent
{
private bool $answer;
private string $textualAnswer = '';

public function __construct(
private readonly string $question,
bool $default = false,
private readonly bool $default = false,
) {
$this->answer = $default;
}
Expand Down Expand Up @@ -81,4 +84,12 @@ public function getCursorPosition(): Point
y: 0,
);
}

public function getStaticComponent(): StaticComponent
{
return new StaticConfirmComponent(
$this->question,
$this->default,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticMultipleChoiceComponent;
use Tempest\Console\Components\StaticComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\Key;

final class MultipleChoiceComponent implements ConsoleComponent
final class MultipleChoiceComponent implements InteractiveComponent, HasStaticComponent
{
public array $selectedOptions = [];
public int $activeOption;
Expand Down Expand Up @@ -88,4 +91,12 @@ public function down(): void
$this->activeOption = 0;
}
}

public function getStaticComponent(): StaticComponent
{
return new StaticMultipleChoiceComponent(
$this->question,
$this->options,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\HasCursor;
use Tempest\Console\HasFooter;
use Tempest\Console\Key;
use Tempest\Console\Point;

final class PasswordComponent implements ConsoleComponent, HasCursor, HasFooter
final class PasswordComponent implements InteractiveComponent, HasCursor, HasFooter
{
public string $password = '';

Expand Down
76 changes: 76 additions & 0 deletions src/Components/Interactive/ProgressBarComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Tempest\Console\Components\Interactive;

use Closure;
use Generator;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticProgressBarComponent;
use Tempest\Console\Components\StaticComponent;

final readonly class ProgressBarComponent implements InteractiveComponent, HasStaticComponent
{
public function __construct(
private iterable $data,
private Closure $handler,
/** @var null|Closure(int $step, int $count): string $format */
private ?Closure $format = null,
) {
}

public function render(): Generator
{
$result = [];

$count = iterator_count($this->data);
$step = 1;

$format = $this->format ?? function (int $step, int $count): string {
$width = 30;

$progress = (int) round(($step / $count) * $width);

if ($step === $count) {
$bar = sprintf(
'[%s]',
str_repeat('=', $width),
);
} else {
$bar = sprintf(
'[%s>%s]',
str_repeat('=', max(0, $progress)),
str_repeat(' ', $width - $progress),
);
}

return sprintf(
'%s (%s/%s)',
$bar,
$step,
$count,
) . PHP_EOL;
};

foreach ($this->data as $item) {
yield $format($step, $count);

$result[] = ($this->handler)($item);

$step += 1;
}

return $result;
}

public function getStaticComponent(): StaticComponent
{
return new StaticProgressBarComponent(
data: $this->data,
handler: $this->handler,
format: $this->format,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Closure;
use Generator;
use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticSearchComponent;
use Tempest\Console\Components\StaticComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\HasCursor;
use Tempest\Console\HasFooter;
use Tempest\Console\Key;
use Tempest\Console\Point;

final class SearchComponent implements ConsoleComponent, HasFooter, HasCursor
final class SearchComponent implements InteractiveComponent, HasFooter, HasCursor, HasStaticComponent
{
public Point $cursorPosition;
public string $query = '';
Expand Down Expand Up @@ -157,4 +160,12 @@ private function isSelected(int $key): bool
{
return $this->selectedOption === $key;
}

public function getStaticComponent(): StaticComponent
{
return new StaticSearchComponent(
label: $this->label,
search: $this->search,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,38 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticSingleChoiceComponent;
use Tempest\Console\Components\StaticComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\Key;

final class QuestionComponent implements ConsoleComponent
final class SingleChoiceComponent implements InteractiveComponent, HasStaticComponent
{
public int $selectedOption;

public function __construct(
public string $question,
public array $options,
public mixed $default = null,
public bool $asList = false,
) {
$this->selectedOption = array_key_first($this->options);
if ($this->default) {
foreach ($this->options as $key => $option) {
if ($option === $this->default) {
$this->selectedOption = $key;

break;
}
}
}

if (! isset($this->selectedOption)) {
$this->selectedOption = array_key_first($this->options);
}
}

public function render(): string
Expand Down Expand Up @@ -63,4 +80,14 @@ public function down(): void
$this->selectedOption = 0;
}
}

public function getStaticComponent(): StaticComponent
{
return new StaticSingleChoiceComponent(
question: $this->question,
options: $this->options,
default: $this->default,
asList: $this->asList,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

declare(strict_types=1);

namespace Tempest\Console\Components;
namespace Tempest\Console\Components\Interactive;

use Tempest\Console\ConsoleComponent;
use Tempest\Console\Components\HasStaticComponent;
use Tempest\Console\Components\InteractiveComponent;
use Tempest\Console\Components\Static\StaticTextBoxComponent;
use Tempest\Console\Components\StaticComponent;
use Tempest\Console\HandlesKey;
use Tempest\Console\HasCursor;
use Tempest\Console\HasFooter;
use Tempest\Console\Key;
use Tempest\Console\Point;

final class TextBoxComponent implements ConsoleComponent, HasFooter, HasCursor
final class TextBoxComponent implements InteractiveComponent, HasFooter, HasCursor, HasStaticComponent
{
public Point $cursorPosition;
public string $answer = '';
Expand Down Expand Up @@ -107,4 +110,9 @@ public function getCursorPosition(): Point
y: $this->cursorPosition->y - 1,
);
}

public function getStaticComponent(): StaticComponent
{
return new StaticTextBoxComponent($this->label);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

declare(strict_types=1);

namespace Tempest\Console;
namespace Tempest\Console\Components;

use Generator;

interface ConsoleComponent
interface InteractiveComponent
{
public function render(): Generator|string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use ReflectionClass;
use ReflectionMethod;
use Tempest\Console\Console;
use Tempest\Console\ConsoleComponent;
use Tempest\Console\Exceptions\InterruptException;
use Tempest\Console\HandlesKey;
use Tempest\Console\Key;
Expand All @@ -17,13 +16,13 @@
use Tempest\Validation\Rule;
use Tempest\Validation\Validator;

final class GenericComponentRenderer implements ComponentRenderer
final class InteractiveComponentRenderer
{
private array $validationErrors = [];

public function render(
Console $console,
ConsoleComponent $component,
InteractiveComponent $component,
array $validation = []
): mixed {
$terminal = new Terminal($console);
Expand Down Expand Up @@ -84,7 +83,7 @@ public function render(
return null;
}

private function resolveHandlers(ConsoleComponent $component): array
private function resolveHandlers(InteractiveComponent $component): array
{
/** @var ReflectionMethod[][] $keyBindings */
$keyBindings = [];
Expand Down
Loading

0 comments on commit 34db7a6

Please sign in to comment.