diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 4e5bd5d..03056a4 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -32,6 +32,16 @@ public function add(Closure $step, ?string $name = null, bool $ignoreWhenReverti return $this; } + /** + * Add a new conditional step. + */ + public function addIf(Closure|bool $condition, Closure $step, ?string $name = null, bool $ignoreWhenReverting = false): self + { + $this->steps[] = new FormStep($step, $condition, $name, $ignoreWhenReverting); + + return $this; + } + /** * Run all of the given steps. * diff --git a/tests/Feature/FormTest.php b/tests/Feature/FormTest.php index 2bd1a4b..442b318 100644 --- a/tests/Feature/FormTest.php +++ b/tests/Feature/FormTest.php @@ -6,6 +6,7 @@ use function Laravel\Prompts\confirm; use function Laravel\Prompts\form; use function Laravel\Prompts\outro; +use function Laravel\Prompts\text; it('can run multiple steps', function () { Prompt::fake([ @@ -179,3 +180,50 @@ Prompt::assertOutputDoesntContain('This should not appear!'); }); + +it('can revert steps with conditions', function () { + Prompt::fake([ + 'L', 'u', 'k', 'e', Key::ENTER, // name + Key::DOWN, Key::ENTER, // JS + Key::CTRL_U, // revert + Key::UP, Key::ENTER, // PHP + '8', '.', '3', Key::ENTER, // version + Key::ENTER, + ]); + + $responses = form() + ->text('What is your name?') + ->select('What is your language?', ['PHP', 'JS']) + ->addIf(fn ($responses) => $responses[1] === 'PHP', fn ($responses) => text("Which version?")) + ->confirm('Are you sure?') + ->submit(); + + expect($responses)->toBe([ + 'Luke', + 'PHP', + '8.3', + true, + ]); +}); + +it('leaves skipped conditional field empty', function () { + Prompt::fake([ + 'L', 'u', 'k', 'e', Key::ENTER, // name + Key::DOWN, Key::ENTER, // JS + Key::ENTER, + ]); + + $responses = form() + ->text('What is your name?') + ->select('What is your language?', ['PHP', 'JS']) + ->addIf(fn ($responses) => $responses[1] === 'PHP', fn ($responses) => text("Which version?")) + ->confirm('Are you sure?') + ->submit(); + + expect($responses)->toBe([ + 'Luke', + 'JS', + null, + true, + ]); +});