Skip to content

Commit ba3e609

Browse files
authored
Add missing session method to state options and related tests (#133)
1 parent d47f3ef commit ba3e609

File tree

7 files changed

+237
-0
lines changed

7 files changed

+237
-0
lines changed

src/Options/StateOptions.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Livewire\Attributes\Locked;
66
use Livewire\Attributes\Modelable;
77
use Livewire\Attributes\Reactive;
8+
use Livewire\Attributes\Session;
89
use Livewire\Attributes\Url;
910
use Livewire\Volt\Property;
1011

@@ -67,6 +68,14 @@ public function reactive(): static
6768
return $this->attribute(Reactive::class);
6869
}
6970

71+
/**
72+
* Indicate the state should be tracked in the session.
73+
*/
74+
public function session(?string $key = null): static
75+
{
76+
return $this->attribute(Session::class, key: $key);
77+
}
78+
7079
/**
7180
* Indicate the state should be tracked in the URL.
7281
*/

tests/Feature/ClassComponentTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,40 @@
2121
->assertSee('Hello World');
2222
});
2323

24+
it('can have session state', function () {
25+
$component = Livewire::test('component-with-session-attribute');
26+
27+
$component->assertSet('tab', 'livewire');
28+
29+
$component->assertSeeHtmlInOrder([
30+
'<li>Livewire 3</li>',
31+
'<li>Laravel Volt</li>',
32+
'<li>Flux UI</li>',
33+
]);
34+
35+
$component->set('tab', 'react');
36+
37+
$component->assertSeeHtmlInOrder([
38+
'<li>React 19</li>',
39+
'<li>Typescript</li>',
40+
'<li>Inertia 2</li>',
41+
'<li>shadcdn/ui</li>',
42+
]);
43+
44+
$component->set('tab', 'vue');
45+
46+
$component->assertSeeHtmlInOrder($tags = [
47+
'<li>Vue 3</li>',
48+
'<li>Typescript</li>',
49+
'<li>Inertia 2</li>',
50+
'<li>shadcdn-vue</li>',
51+
]);
52+
53+
$component->refresh();
54+
55+
$component->assertSeeHtmlInOrder($tags);
56+
});
57+
2458
it('can have url attribute', function () {
2559
$component = Livewire::test('component-with-url-attribute');
2660

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
use Livewire\Volt\CompileContext;
4+
use Livewire\Volt\Compiler;
5+
6+
use function Livewire\Volt\state;
7+
8+
it('may not be defined', function () {
9+
$code = Compiler::contextToString(CompileContext::instance());
10+
11+
expect($code)->not->toContain('#[\Livewire\Attributes\Session()]');
12+
});
13+
14+
it('may be defined', function () {
15+
state('tabOne')->session();
16+
state('tabTwo')->session(key: 'tab');
17+
18+
$code = Compiler::contextToString(CompileContext::instance());
19+
20+
expect($code)->toContain(
21+
<<<'PHP'
22+
#[\Livewire\Attributes\Session()]
23+
public $tabOne;
24+
25+
#[\Livewire\Attributes\Session(key: 'tab')]
26+
public $tabTwo;
27+
PHP
28+
);
29+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Livewire\Attributes\Session;
4+
use Livewire\Volt\CompileContext;
5+
use Pest\Expectation;
6+
7+
use function Livewire\Volt\state;
8+
9+
it('may be defined', function () {
10+
$context = CompileContext::instance();
11+
12+
state('name');
13+
state(tabOne: 1)->session();
14+
state(tabTwo: 2)->session(key: 'tab');
15+
16+
expect($context->state)->toHaveKeys(['name', 'tabOne', 'tabTwo'])
17+
->sequence(
18+
fn (Expectation $property) => $property->attributes->toBe([]),
19+
fn (Expectation $property) => $property->attributes->toBe([
20+
Session::class => [],
21+
]),
22+
fn (Expectation $property) => $property->attributes->toBe([
23+
Session::class => [
24+
'key' => 'tab',
25+
],
26+
]),
27+
);
28+
});

tests/Feature/FunctionalComponentTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,40 @@
288288
$component->assertSet('with', 'value');
289289
});
290290

291+
it('can have session state', function () {
292+
$component = Livewire::test('component-with-session-state');
293+
294+
$component->assertSet('tab', 'livewire');
295+
296+
$component->assertSeeHtmlInOrder([
297+
'<li>Livewire 3</li>',
298+
'<li>Laravel Volt</li>',
299+
'<li>Flux UI</li>',
300+
]);
301+
302+
$component->set('tab', 'react');
303+
304+
$component->assertSeeHtmlInOrder([
305+
'<li>React 19</li>',
306+
'<li>Typescript</li>',
307+
'<li>Inertia 2</li>',
308+
'<li>shadcdn/ui</li>',
309+
]);
310+
311+
$component->set('tab', 'vue');
312+
313+
$component->assertSeeHtmlInOrder($tags = [
314+
'<li>Vue 3</li>',
315+
'<li>Typescript</li>',
316+
'<li>Inertia 2</li>',
317+
'<li>shadcdn-vue</li>',
318+
]);
319+
320+
$component->refresh();
321+
322+
$component->assertSeeHtmlInOrder($tags);
323+
});
324+
291325
it('can have url state', function () {
292326
$component = Livewire::test('component-with-url-state');
293327

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
use Livewire\Attributes\Computed;
4+
use Livewire\Attributes\Session;
5+
use Livewire\Volt\Component;
6+
7+
new class extends Component
8+
{
9+
#[Session]
10+
public $tab = 'livewire';
11+
12+
#[Computed]
13+
public function tags()
14+
{
15+
return collect([
16+
'react' => [
17+
'React 19',
18+
'Typescript',
19+
'Inertia 2',
20+
'shadcdn/ui',
21+
],
22+
'vue' => [
23+
'Vue 3',
24+
'Typescript',
25+
'Inertia 2',
26+
'shadcdn-vue',
27+
],
28+
'livewire' => [
29+
'Livewire 3',
30+
'Laravel Volt',
31+
'Flux UI',
32+
],
33+
][$this->tab] ?? []);
34+
}
35+
}; ?>
36+
37+
<div>
38+
<h1>Choose your Starter Kit:</h1>
39+
40+
<input wire:model="tab" type="radio" id="react" name="tab" value="react">
41+
<label for="react">React</label>
42+
43+
<input wire:model="tab" type="radio" id="vue" name="tab" value="vue">
44+
<label for="vue">Vue</label>
45+
46+
<input wire:model="tab" type="radio" id="livewire" name="tab" value="livewire">
47+
<label for="livewire">Livewire</label>
48+
49+
<ul>
50+
@foreach($this->tags as $tag)
51+
<li>{{ $tag }}</li>
52+
@endforeach
53+
</ul>
54+
</div>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
use function Livewire\Volt\computed;
4+
use function Livewire\Volt\state;
5+
6+
state(tab: 'livewire')->session();
7+
8+
$tags = computed(function () {
9+
return collect([
10+
'react' => [
11+
'React 19',
12+
'Typescript',
13+
'Inertia 2',
14+
'shadcdn/ui',
15+
],
16+
'vue' => [
17+
'Vue 3',
18+
'Typescript',
19+
'Inertia 2',
20+
'shadcdn-vue',
21+
],
22+
'livewire' => [
23+
'Livewire 3',
24+
'Laravel Volt',
25+
'Flux UI',
26+
],
27+
][$this->tab] ?? []);
28+
});
29+
30+
?>
31+
32+
<div>
33+
<h1>Choose your Starter Kit:</h1>
34+
35+
<input wire:model="tab" type="radio" id="react" name="tab" value="react">
36+
<label for="react">React</label>
37+
38+
<input wire:model="tab" type="radio" id="vue" name="tab" value="vue">
39+
<label for="vue">Vue</label>
40+
41+
<input wire:model="tab" type="radio" id="livewire" name="tab" value="livewire">
42+
<label for="livewire">Livewire</label>
43+
44+
<ul>
45+
@foreach($this->tags as $tag)
46+
<li>{{ $tag }}</li>
47+
@endforeach
48+
</ul>
49+
</div>

0 commit comments

Comments
 (0)