diff --git a/src/Form/Step.php b/src/Form/Step.php index 63dc026e..a82a4404 100644 --- a/src/Form/Step.php +++ b/src/Form/Step.php @@ -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 @@ -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, + ]; } } diff --git a/src/Livewire/Concerns/WithFields.php b/src/Livewire/Concerns/WithFields.php index ae5f7f9b..c936bd74 100644 --- a/src/Livewire/Concerns/WithFields.php +++ b/src/Livewire/Concerns/WithFields.php @@ -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 { diff --git a/src/Livewire/Concerns/WithSteps.php b/src/Livewire/Concerns/WithSteps.php index 6c1d7444..46818fc6 100644 --- a/src/Livewire/Concerns/WithSteps.php +++ b/src/Livewire/Concerns/WithSteps.php @@ -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 @@ -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 diff --git a/src/Livewire/Synthesizers/StepSynth.php b/src/Livewire/Synthesizers/StepSynth.php index 44f5f1df..74f61c0d 100644 --- a/src/Livewire/Synthesizers/StepSynth.php +++ b/src/Livewire/Synthesizers/StepSynth.php @@ -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']), + ); } }