Skip to content

Commit f4d8c41

Browse files
authored
Splade v0.5 (#51)
* Refactored Transitions + Public Transition/Animation API (#50) * Persistent layout (#47) * Teleport component * Lazy loading (#53)
1 parent 1221191 commit f4d8c41

File tree

94 files changed

+1546
-253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+1546
-253
lines changed

ExtractTransitionClasses.php

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
use ProtoneMedia\Splade\ServiceProvider;
4+
use ProtoneMedia\Splade\TransitionRepository;
5+
6+
require __DIR__ . '/vendor/autoload.php';
7+
8+
$transitionRepository = new TransitionRepository;
9+
10+
ServiceProvider::registerTransitionAnimations($transitionRepository);
11+
12+
$classes = implode(' ', $transitionRepository->classes());
13+
14+
file_put_contents(
15+
__DIR__ . '/resources/views/transitions/classes.blade.php',
16+
"<div class='{$classes}'>\n<!-- This is an automatically generated template so that Tailwind won't purge these transition classes... -->\n</div>",
17+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use ProtoneMedia\Splade\Facades\Splade;
6+
7+
class LazyController
8+
{
9+
public function show()
10+
{
11+
$sleep = request()->query('sleep', 1);
12+
13+
return view('lazy', [
14+
'always' => 'always',
15+
'init' => Splade::onInit('init'),
16+
'lazy' => Splade::onLazy(fn () => sleep($sleep) ? null : ['key' => 'Hi from controller!']),
17+
'time' => Splade::onLazy(fn () => sleep($sleep) ? null : now()->format('H:i:s')),
18+
]);
19+
}
20+
21+
public function notifications()
22+
{
23+
return view('notifications', [
24+
'notifications' => Splade::onLazy(fn () => sleep(1) ? null : ['Notification 1', 'Notification 2']),
25+
]);
26+
}
27+
}

app/app/Http/Controllers/NavigationController.php

+10
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,14 @@ public function form()
3333
{
3434
return view('navigation.form');
3535
}
36+
37+
public function videoOne()
38+
{
39+
return view('navigation.videoOne');
40+
}
41+
42+
public function videoTwo()
43+
{
44+
return view('navigation.videoTwo');
45+
}
3646
}

app/app/View/Components/Header.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\View\Components;
4+
5+
use Illuminate\View\Component;
6+
7+
class Header extends Component
8+
{
9+
/**
10+
* Create a new component instance.
11+
*
12+
* @return void
13+
*/
14+
public function __construct(public string $title)
15+
{
16+
//
17+
}
18+
19+
/**
20+
* Get the view / contents that represent the component.
21+
*
22+
* @return \Illuminate\Contracts\View\View|\Closure|string
23+
*/
24+
public function render()
25+
{
26+
return view('components.header');
27+
}
28+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\View\Components;
4+
5+
use ProtoneMedia\Splade\Components\PersistentComponent;
6+
7+
class VideoLayout extends PersistentComponent
8+
{
9+
public function render()
10+
{
11+
return view('navigation.videoLayout');
12+
}
13+
}

app/public/video_no_audio.mp4

321 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div>
2+
<h4>{{ $title }}</h4>
3+
<h5>{{ $subtitle }}</h5>
4+
<h6>{{ $attributes->get('help') }}</h6>
5+
6+
<div dusk="header-slot">{{ $slot }}</div>
7+
</div>

app/resources/views/lazy.blade.php

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
@extends('layout')
2+
3+
@section('content')
4+
5+
LazyComponent
6+
7+
<h1>{{ $always }}</h1>
8+
<h2>{{ $init }}</h2>
9+
10+
<x-splade-lazy attr1="1">
11+
<x-slot:placeholder>
12+
<p>Placeholder 1</p>
13+
</x-slot:placeholder>
14+
15+
<h3>Lazy slot 1 : {{ $lazy['key'] }}</h3>
16+
</x-splade-lazy>
17+
18+
<x-splade-lazy attr2="2">
19+
<x-slot:placeholder>
20+
<p>Placeholder 2</p>
21+
</x-slot:placeholder>
22+
23+
<h4>Lazy slot 2 : {{ $lazy['key'] }}</h4>
24+
</x-splade-lazy>
25+
26+
<x-splade-toggle>
27+
<button class="block" @click="toggle">Load notifications</button>
28+
29+
<x-splade-lazy show="toggled" url="/lazy/notifications">
30+
<x-slot:placeholder>
31+
<p>Loading notifications...</p>
32+
</x-slot:placeholder>
33+
</x-splade-lazy>
34+
</x-splade-toggle>
35+
36+
<x-splade-toggle>
37+
<button class="block" @click="toggle">Load time</button>
38+
39+
<x-splade-lazy show="toggled">
40+
<x-slot:placeholder>
41+
<p>Want to see the time?</p>
42+
</x-slot:placeholder>
43+
44+
<h5>{{ $time }}</h5>
45+
</x-splade-lazy>
46+
</x-splade-toggle>
47+
48+
@endsection

app/resources/views/navigation/nav.blade.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<Link dusk="three" href="/navigation/three">Three</Link>
55
<Link dusk="notFound" href="/navigation/notFound">notFound</Link>
66
<Link dusk="serverError" href="/navigation/serverError">serverError</Link>
7+
<Link dusk="video" href="/navigation/video/one">Video</Link>
8+
<Link dusk="lazy" href="/lazy">Lazy</Link>
79

810
<Link confirm dusk="confirm" href="/navigation/two">Confirm to two</Link>
911
<Link
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div class="container mt-4 mx-auto">
2+
<h1 class="text-3xl mb-8">{{ $title }}</h1>
3+
4+
{{ $subtitle }}
5+
6+
{{ $slot }}
7+
8+
<div class="fixed bottom-0 left-0 flex justify-between items-center bg-indigo-50 w-full">
9+
<h3 class="text-xl ml-8">Persistent Video</h3>
10+
<video class="w-full max-w-[16rem] aspect-video" controls loop muted>
11+
<source src="/video_no_audio.mp4" type="video/mp4">
12+
</video>
13+
</div>
14+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<x-video-layout>
2+
<x-slot:title> Title for Chapter 1 </x-slot>
3+
4+
<x-slot:subtitle> Subtitle for Chapter 1 </x-slot>
5+
6+
<x-header title="Title eno" help="Helptext">
7+
<x-slot:subtitle> Subtitle eno </x-slot:subtitle>
8+
9+
HeaderSlot
10+
</x-header>
11+
12+
<article class="prose mt-8">
13+
<h2>Chapter one</h2>
14+
15+
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam cum non quod, sint optio nam possimus at. Illum, dolores similique, unde sed reiciendis quibusdam quas iste cumque, facere eaque porro.</p>
16+
17+
<Link dusk="two" href="/navigation/video/two">Go to Chapter two</Link>
18+
19+
<form>
20+
<input name="persistent_video_one" />
21+
</form>
22+
23+
<Link dusk="nav" href="/navigation/one">Back to nav</Link>
24+
</article>
25+
</x-video-layout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<x-video-layout>
2+
<x-slot:title> Title for Chapter 2 </x-slot>
3+
4+
<x-slot:subtitle> Subtitle for Chapter 2 </x-slot>
5+
6+
<article class="prose mt-8">
7+
<h2>Chapter two</h2>
8+
9+
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
10+
11+
<Link href="/navigation/video/one">Go back to Chapter one</Link>
12+
13+
<form>
14+
<input name="persistent_video_two" />
15+
</form>
16+
17+
<Link dusk="nav" href="/navigation/one">Back to nav</Link>
18+
</article>
19+
</x-video-layout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@foreach($notifications as $notification)
2+
<p>{{ $notification }}</p>
3+
@endforeach
4+
5+
<x-splade-form>
6+
<x-splade-input name="date" date />
7+
</x-splade-form>
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@extends('layout')
2+
3+
@section('content')
4+
5+
TeleportComponent
6+
7+
<x-splade-form>
8+
<input dusk="name" v-model="form.name" />
9+
10+
<x-splade-teleport to="#footer">
11+
<p v-text="form.name" />
12+
</x-splade-teleport>
13+
</x-splade-form>
14+
15+
<div id="footer" class="p-4 bg-green-500 text-white" />
16+
17+
@endsection
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@extends('layout')
2+
3+
@section('content')
4+
5+
@php
6+
\ProtoneMedia\Splade\Facades\Animation::new(
7+
name: 'custom-demo',
8+
enter: 'transform transform ease-in-out duration-300',
9+
enterFrom: 'opacity-0 -translate-x-full',
10+
enterTo: 'opacity-100 translate-x-0',
11+
leave: 'transform transform ease-in-out duration-300',
12+
leaveFrom: 'opacity-100 translate-x-0',
13+
leaveTo: 'opacity-0 -translate-x-full',
14+
);
15+
@endphp
16+
17+
TransitionDefault
18+
19+
<x-splade-toggle>
20+
<button @click.prevent="toggle">Toggle</button>
21+
22+
<div class="p-4 bg-red-500">
23+
<x-splade-transition animation="custom-demo" show="toggled">
24+
<div class="bg-green-500 p-4">Slot</div>
25+
</x-splade-transition>
26+
</div>
27+
</x-splade-toggle>
28+
29+
@endsection

app/routes/web.php

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use App\Http\Controllers\FormComponentsController;
1010
use App\Http\Controllers\FormRelationsController;
1111
use App\Http\Controllers\FormViewController;
12+
use App\Http\Controllers\LazyController;
1213
use App\Http\Controllers\ModalController;
1314
use App\Http\Controllers\NavigationController;
1415
use App\Http\Controllers\NestedFormController;
@@ -115,10 +116,15 @@
115116

116117
Route::get('form/relations/twoForms', [FormRelationsController::class, 'twoForms'])->name('form.relations.twoForms');
117118

119+
Route::get('lazy', [LazyController::class, 'show'])->name('lazy');
120+
Route::get('lazy/notifications', [LazyController::class, 'notifications'])->name('lazy.notifications');
121+
118122
Route::get('navigation/one/{id?}', [NavigationController::class, 'one'])->name('navigation.one');
119123
Route::get('navigation/two', [NavigationController::class, 'two'])->name('navigation.two');
120124
Route::get('navigation/three', [NavigationController::class, 'three'])->name('navigation.three');
121125
Route::get('navigation/form', [NavigationController::class, 'form'])->name('navigation.form');
126+
Route::get('navigation/video/one', [NavigationController::class, 'videoOne'])->name('navigation.videoOne');
127+
Route::get('navigation/video/two', [NavigationController::class, 'videoTwo'])->name('navigation.videoTwo');
122128

123129
Route::get('navigation/notFound', fn () => abort(404))->name('navigation.notFound');
124130
Route::get('navigation/serverError', fn () => throw new Exception('Whoops!'))->name('navigation.serverError');
@@ -143,6 +149,8 @@
143149
return view('state');
144150
})->name('state');
145151

152+
Route::view('teleport', 'teleport')->name('teleport');
153+
146154
Route::get('toast/infoLeftTop', [ToastController::class, 'infoLeftTop'])->name('toast.infoLeftTop');
147155
Route::get('toast/infoCenterTop', [ToastController::class, 'infoCenterTop'])->name('toast.infoCenterTop');
148156
Route::get('toast/infoRightTop', [ToastController::class, 'infoRightTop'])->name('toast.infoRightTop');
@@ -158,6 +166,8 @@
158166
Route::view('toggle/single', 'toggle.single')->name('toggle.single');
159167
Route::view('toggle/multiple', 'toggle.multiple')->name('toggle.multiple');
160168

169+
Route::view('transition/default', 'transition.default')->name('transition.default');
170+
161171
Route::prefix('table')->group(function () {
162172
$table = new UserTableView;
163173

app/tests/Browser/LazyTest.php

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Tests\Browser;
4+
5+
use Laravel\Dusk\Browser;
6+
use Tests\DuskTestCase;
7+
8+
class LazyTest extends DuskTestCase
9+
{
10+
/** @test */
11+
public function it_can_lazily_load_content()
12+
{
13+
$this->browse(function (Browser $browser) {
14+
$browser->visit('/lazy')
15+
->waitForText('LazyComponent')
16+
->assertSee('Placeholder 1')
17+
->assertSee('Placeholder 2')
18+
->waitForText('Lazy slot 1 : Hi from controller!')
19+
->waitForText('Lazy slot 2 : Hi from controller!')
20+
->press('Load time')
21+
->assertSee('Want to see the time?')
22+
->waitUntilMissingText('Want to see the time?')
23+
->assertSee($time = now()->format('H:i'))
24+
->press('Load time')
25+
->assertDontSee($time)
26+
->press('Load time')
27+
->assertSee('Want to see the time?')
28+
->waitUntilMissingText('Want to see the time?')
29+
->assertSee(now()->format('H:i'));
30+
});
31+
}
32+
33+
/** @test */
34+
public function it_can_resolve_an_external_url()
35+
{
36+
$this->browse(function (Browser $browser) {
37+
$browser->visit('/lazy?sleep=0')
38+
->waitForText('LazyComponent')
39+
->press('Load notifications')
40+
->assertSee('Loading notifications...')
41+
->waitUntilMissingText('Loading notifications..')
42+
->assertSee('Notification 1')
43+
->assertSee('Notification 2')
44+
45+
// assert other components are mounted as well:
46+
->click('input[name="date"]')
47+
->waitFor('.flatpickr-calendar.open')
48+
->click('.flatpickr-calendar.open .flatpickr-day.today')
49+
->assertInputValue('date', now()->format('Y-m-d'));
50+
});
51+
}
52+
}

0 commit comments

Comments
 (0)