Skip to content

Commit

Permalink
add skip step functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
satoved committed Sep 26, 2024
1 parent 51ce010 commit 00a8d68
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 9 deletions.
17 changes: 17 additions & 0 deletions src/Livewire/Forms/StepForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace Satoved\LivewireSteps\Livewire\Forms;

use Closure;
use Livewire\Form;
use Satoved\LivewireSteps\Livewire\WizardComponent;

abstract class StepForm extends Form
{
protected ?Closure $skipCondition = null;

abstract public function render();

public static function id(): string
Expand Down Expand Up @@ -47,6 +50,20 @@ public function isFirst(): bool
return $this->index() === 0;
}

public function shouldBeSkipped(): bool
{
if ($this->skipCondition !== null) {
return ($this->skipCondition)();
}

return false;
}

public function skipIf(Closure $skipCondition): void
{
$this->skipCondition = $skipCondition;
}

public function isLast(): bool
{
return $this->index() === ($this->getComponent()->totalSteps() - 1);
Expand Down
14 changes: 9 additions & 5 deletions src/Livewire/WizardComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,20 @@ protected function currentStep(): StepForm
*/
public function nextStep(): void
{
if ($this->currentStepIndex === $this->totalSteps() - 1) {
throw NoNextStep::make(self::class, get_class($this->currentStep()));
}
do {
if ($this->currentStepIndex === $this->totalSteps() - 1) {
throw NoNextStep::make(self::class, get_class($this->currentStep()));
}

$this->currentStepIndex++;
$this->currentStepIndex++;
} while ($this->currentStep()->shouldBeSkipped());
}

public function previousStep(): void
{
$this->currentStepIndex = max(0, $this->currentStepIndex - 1);
do {
$this->currentStepIndex = max(0, $this->currentStepIndex - 1);
} while ($this->currentStepIndex !== 0 && $this->currentStep()->shouldBeSkipped());
}

protected function isFirstStep(): bool
Expand Down
18 changes: 18 additions & 0 deletions tests/TestSupport/Steps/SkipStepForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Satoved\LivewireSteps\Tests\TestSupport\Steps;

use Satoved\LivewireSteps\Livewire\Forms\StepForm;

class SkipStepForm extends StepForm
{
public function shouldBeSkipped(): bool
{
return true;
}

public function render()
{
return '__SKIP_STEP_BODY__';
}
}
56 changes: 52 additions & 4 deletions tests/WizardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Satoved\LivewireSteps\Tests\TestSupport\MyWizardComponent;
use Satoved\LivewireSteps\Tests\TestSupport\Steps\FirstStepForm;
use Satoved\LivewireSteps\Tests\TestSupport\Steps\SecondStepForm;
use Satoved\LivewireSteps\Tests\TestSupport\Steps\SkipStepForm;
use Satoved\LivewireSteps\Tests\TestSupport\Steps\SomeIntricateNameStepForm;

$it = it('can render a wizard component', function () {
Expand All @@ -22,7 +23,7 @@
->assertSee('__SECOND_STEP_BODY__');
});

it('can render the next and previous step', function () {
it('can go to the next and previous steps', function () {
Livewire::test(MyWizardComponent::class)
->assertSee('__FIRST_STEP_BODY__')
->call('nextStep')
Expand All @@ -31,6 +32,54 @@
->assertSee('__FIRST_STEP_BODY__');
});

it('can skip steps', function () {
$class = new class extends WizardComponent {
public FirstStepForm $firstStepForm;
public SkipStepForm $skipTestForm;
public SecondStepForm $secondStepForm;

public function render()
{
return '<div>{{ $this->renderStep() }}</div>';
}
};

Livewire::test($class)
->assertSee('__FIRST_STEP_BODY__')
->call('nextStep')
->assertSee('__SECOND_STEP_BODY__')
->call('previousStep')
->assertSee('__FIRST_STEP_BODY__');
});


it('can skip steps via closure', function () {
$class = new class extends WizardComponent {
public FirstStepForm $firstStepForm;
public SomeIntricateNameStepForm $toSkipStepForm;
public SecondStepForm $secondStepForm;

public function booted()
{
$this->toSkipStepForm->skipIf(function () {
return true;
});
}

public function render()
{
return '<div>{{ $this->renderStep() }}</div>';
}
};

Livewire::test($class)
->assertSee('__FIRST_STEP_BODY__')
->call('nextStep')
->assertSee('__SECOND_STEP_BODY__')
->call('previousStep')
->assertSee('__FIRST_STEP_BODY__');
});

it('throws an exception when going to the next step on the last step', function () {
Livewire::test(MyWizardComponent::class, ['currentStepIndex' => 1])
->call('nextStep');
Expand Down Expand Up @@ -66,8 +115,7 @@
});

it('has default labels for steps', function () {
$class = new class extends WizardComponent
{
$class = new class extends WizardComponent {
public SomeIntricateNameStepForm $someIntricateNameStepForm;

public function render()
Expand Down Expand Up @@ -119,4 +167,4 @@ public function render()

return true;
});
});
});

0 comments on commit 00a8d68

Please sign in to comment.