Skip to content

Commit

Permalink
Make steps independent of sections
Browse files Browse the repository at this point in the history
  • Loading branch information
aerni committed Apr 23, 2024
1 parent 7b1a5a3 commit 1093665
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 23 deletions.
50 changes: 41 additions & 9 deletions src/Form/Step.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,50 @@
namespace Aerni\LivewireForms\Form;

use Livewire\Livewire;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Aerni\LivewireForms\Enums\StepStatus;
use Illuminate\Contracts\Support\Arrayable;

class Step
class Step implements Arrayable
{
public function __construct(
public int $number,
public StepStatus $status,
protected Collection $fields,
protected ?string $display,
protected ?string $instructions,
) {
}

public function handle(): string
{
return Str::snake($this->display ?? $this->number);
}

public function id(): string
{
return $this->number . '-step';
return Livewire::current()->getId().'-step-'.$this->number;
}

public function display(): ?string
{
return __($this->display);
}

public function instructions(): ?string
{
return __($this->instructions);
}

public function fields(): Collection
{
return $this->fields;
}

public function number(): int
{
return $this->number;
}

public function isPrevious(): bool
Expand All @@ -38,13 +69,14 @@ public function show(): string
return "showStep({$this->number})";
}

public function section(): Section
{
return Livewire::current()->sections->firstWhere(fn (Section $section) => $section->order () === $this->number);
}

public function __call($name, $arguments)
public function toArray(): array
{
return $this->section()->$name($arguments);
return [
'number' => $this->number,
'fields' => $this->fields,
'status' => $this->status->value,
'display' => $this->display,
'instructions' => $this->instructions,
];
}
}
1 change: 1 addition & 0 deletions src/Livewire/Concerns/WithFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ protected function makeFieldFromModel(StatamicField $field): Field
: throw new \Exception("The field model binding for fieldtype [{$fieldtype}] cannot be found.");
}

// TODO: Move sections into its own trait like steps.
#[Computed]
public function sections(): Collection
{
Expand Down
22 changes: 15 additions & 7 deletions src/Livewire/Concerns/WithSteps.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

trait WithSteps
{
// TODO: Do we really need a synth or can we just use a computed property?
public Collection $steps;

public function mountWithSteps(): void
Expand All @@ -20,13 +21,20 @@ public function mountWithSteps(): void

protected function steps(): Collection
{
return $this->sections
->mapWithKeys(function (Section $section) {
$status = $section->order() === 1
? StepStatus::Current : StepStatus::Next;

return [$section->order() => new Step($section->order(), $status)];
});
return $this->form->blueprint()->tabs()->first()->sections()
->filter(fn ($section) => $section->fields()->all()->isNotEmpty())
->values()
->mapWithKeys(function ($section, $index) {
$number = $index + 1;

return [$number => new Step(
number: $number,
status: $number === 1 ? StepStatus::Current : StepStatus::Next,
fields: $this->fields->intersectByKeys($section->fields()->all()),
display: $section->display(),
instructions: $section->instructions(),
)];
});
}

public function currentStep(): Step
Expand Down
30 changes: 23 additions & 7 deletions src/Livewire/Synthesizers/StepSynth.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,32 @@ public static function match($target)
return $target instanceof Step;
}

public function dehydrate($target)
public function dehydrate($target, $dehydrateChild)
{
return [[
'number' => $target->number,
'status' => $target->status->value,
], []];
$data = $target->toArray();

foreach ($data as $key => $child) {
$data[$key] = $dehydrateChild($key, $child);
}

return [
$data,
['class' => get_class($target)],
];
}

public function hydrate($value)
public function hydrate($value, $meta, $hydrateChild)
{
return new Step($value['number'], StepStatus::from($value['status']));
foreach ($value as $key => $child) {
$value[$key] = $hydrateChild($key, $child);
}

return new Step(
number: $value['number'],
fields: $value['fields'],
display: $value['display'],
instructions: $value['instructions'],
status: StepStatus::from($value['status']),
);
}
}

0 comments on commit 1093665

Please sign in to comment.