release/v0.4.1 #66

Merged
myrmidex merged 4 commits from release/v0.4.1 into main 2026-08-16 13:26:23 +02:00
4 changed files with 88 additions and 64 deletions
Showing only changes of commit e5c257d94d - Show all commits

View file

@ -31,8 +31,10 @@ public function mount(): void
$tracker = Tracker::current(); $tracker = Tracker::current();
$this->needsOnboarding = $tracker === null; $this->needsOnboarding = $tracker === null;
$this->count = $tracker === null ? 0 : $tracker->count;
$this->value = $this->count; if ($tracker !== null) {
$this->syncFrom($tracker);
}
} }
public function initialise(): void public function initialise(): void
@ -45,7 +47,7 @@ public function initialise(): void
'count' => $this->value, 'count' => $this->value,
]); ]);
$this->count = $tracker->count; $this->syncFrom($tracker);
$this->needsOnboarding = false; $this->needsOnboarding = false;
} }
@ -58,10 +60,8 @@ public function increment(): void
} }
$tracker->increment('count'); $tracker->increment('count');
$tracker->refresh();
$this->count = $tracker->count; $this->syncFrom($tracker->refresh());
$this->value = $this->count;
} }
public function edit(): void public function edit(): void
@ -83,7 +83,7 @@ public function save(): void
$tracker->update(['count' => $this->value]); $tracker->update(['count' => $this->value]);
$this->count = (int) $this->value; $this->syncFrom($tracker);
$this->editing = false; $this->editing = false;
} }
@ -94,6 +94,15 @@ public function cancel(): void
$this->editing = false; $this->editing = false;
} }
/**
* The tracker is the source of truth; the form input always mirrors it.
*/
private function syncFrom(Tracker $tracker): void
{
$this->count = $tracker->count;
$this->value = $this->count;
}
public function render(): View public function render(): View
{ {
return view('livewire.counter')->layout('layouts.app'); return view('livewire.counter')->layout('layouts.app');

View file

@ -0,0 +1,48 @@
@props([
'action',
'label',
'submit',
'id' => 'value',
'cancel' => false,
])
<form wire:submit="{{ $action }}" class="space-y-4">
<label for="{{ $id }}" class="text-red-400 font-mono text-xs uppercase tracking-wider">
&gt; {{ $label }}
</label>
<input
id="{{ $id }}"
type="number"
min="0"
step="1"
autofocus
wire:model="value"
class="w-full bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red px-3 py-2"
>
@error('value')
<p class="text-red-400 font-mono text-xs">{{ $message }}</p>
@enderror
<div @class(['flex gap-3 pt-2' => $cancel])>
<button
type="submit"
@class([
'bg-red-500 hover:bg-red-500 text-black font-mono text-sm font-bold border-red-500 rounded-none border-2 uppercase tracking-wider transition-all glow-red px-4 py-2',
'flex-1' => $cancel,
'w-full' => ! $cancel,
])
>
{{ $submit }}
</button>
@if ($cancel)
<button
type="button"
wire:click="cancel"
class="flex-1 bg-black border-red-500 text-red-400 hover:bg-red-950 hover:text-red-300 font-mono text-sm font-bold rounded-none border-2 uppercase tracking-wider transition-all glow-red px-4 py-2"
>
[ABORT]
</button>
@endif
</div>
</form>

View file

@ -3,30 +3,12 @@
<div class="min-h-screen flex items-center justify-center p-4"> <div class="min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-md"> <div class="w-full max-w-md">
<div class="border-2 border-red-500 bg-black shadow-[0_0_20px_rgba(239,68,68,0.3)] p-8"> <div class="border-2 border-red-500 bg-black shadow-[0_0_20px_rgba(239,68,68,0.3)] p-8">
<form wire:submit="initialise" class="space-y-4"> <x-counter-form
<label for="starting-value" class="text-red-400 font-mono text-xs uppercase tracking-wider"> action="initialise"
&gt; Starting Value label="Starting Value"
</label> submit="[INITIALIZE]"
<input id="starting-value"
id="starting-value" />
type="number"
min="0"
step="1"
autofocus
wire:model="value"
class="w-full bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red px-3 py-2"
>
@error('value')
<p class="text-red-400 font-mono text-xs">{{ $message }}</p>
@enderror
<button
type="submit"
class="w-full bg-red-500 hover:bg-red-500 text-black font-mono text-sm font-bold border-red-500 rounded-none border-2 uppercase tracking-wider transition-all glow-red px-4 py-2"
>
[INITIALIZE]
</button>
</form>
</div> </div>
</div> </div>
</div> </div>
@ -59,39 +41,13 @@ class="text-red-400/60 hover:text-red-400 font-mono text-xs uppercase tracking-w
@if ($editing) @if ($editing)
<div class="bg-black p-8"> <div class="bg-black p-8">
<div class="w-full border-4 border-red-500 p-6 bg-black glow-red"> <div class="w-full border-4 border-red-500 p-6 bg-black glow-red">
<form wire:submit="save" class="space-y-4"> <x-counter-form
<label for="count" class="text-red-400 font-mono text-xs uppercase tracking-wider"> action="save"
&gt; Set Value label="Set Value"
</label> submit="[EXECUTE]"
<input id="count"
id="count" :cancel="true"
type="number" />
min="0"
step="1"
autofocus
wire:model="value"
class="w-full bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red px-3 py-2"
>
@error('value')
<p class="text-red-400 font-mono text-xs">{{ $message }}</p>
@enderror
<div class="flex gap-3 pt-2">
<button
type="submit"
class="flex-1 bg-red-500 hover:bg-red-500 text-black font-mono text-sm font-bold border-red-500 rounded-none border-2 uppercase tracking-wider transition-all glow-red px-4 py-2"
>
[EXECUTE]
</button>
<button
type="button"
wire:click="cancel"
class="flex-1 bg-black border-red-500 text-red-400 hover:bg-red-950 hover:text-red-300 font-mono text-sm font-bold rounded-none border-2 uppercase tracking-wider transition-all glow-red px-4 py-2"
>
[ABORT]
</button>
</div>
</form>
</div> </div>
</div> </div>
@endif @endif

View file

@ -29,6 +29,17 @@ public function test_the_page_renders_the_current_count(): void
->assertSee('42'); ->assertSee('42');
} }
public function test_the_edit_form_renders_with_both_actions(): void
{
$this->tracker(42);
Livewire::test(Counter::class)
->call('edit')
->assertSee('Set Value')
->assertSee('[EXECUTE]')
->assertSee('[ABORT]');
}
public function test_increment_adds_exactly_one(): void public function test_increment_adds_exactly_one(): void
{ {
$tracker = $this->tracker(5); $tracker = $this->tracker(5);