A package that allow overlapping (virtually) infinite slideovers simultaneously with configurable widths.
This package is based upon wire-elements/modal (thanks Philo Hermans).
To get started, require the package via Composer:
composer require aristridely/slideover
Add the Livewire directive @livewire('livewire-ui-slideover')
to your template.
<html>
<body>
<!-- content -->
@livewire('livewire-ui-slideover')
</body>
</html>
Requires Alpine. You can use the official CDN to quickly include Alpine:
<!-- Alpine v3 -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
The base slideover template is made with TailwindCSS. If you use a different CSS framework I recommend that you publish the slideover template and change the markup to include the required classes for your CSS framework.
php artisan vendor:publish --tag=livewire-ui-slideover-views
You can run php artisan make:livewire EditUserSlideover
to make the initial Livewire component. Open your component class and make sure it extends the SlideoverComponent
class:
<?php
namespace App\Http\Livewire;
use LivewireUI\Slideover\SlideoverComponent;
class EditUserSlideover extends SlideoverComponent
{
public function render()
{
return view('livewire.edit-user-slideover');
}
}
To open a slideover you will need to emit an event. To open the EditUserSlideover
slideover for example:
<!-- Outside of any Livewire component -->
<button onclick="Livewire.emit('openSlideover', 'edit-user-slideover')">Edit User</button>
<!-- Inside existing Livewire component -->
<button wire:click="$emit('openSlideover', 'edit-user-slideover')">Edit User</button>
<!-- Taking namespace into account for component Admin/EditUser -->
<button wire:click="$emit('openSlideover', 'admin.edit-user-slideover')">Edit User</button>
To open the EditUserSlideover
slideover for a specific user we can pass the user id (notice the single quotes):
<!-- Outside of any Livewire component -->
<button onclick='Livewire.emit(
"openSlideover",
"edit-user-slideover",
{{ json_encode(["user" => $user->id]) }})'
>Edit User</button>
<!-- Inside existing Livewire component -->
<button wire:click='$emit(
"openSlideover",
"edit-user-slideover",
{{ json_encode(["user" => $user->id]) }})'
>Edit User</button>
<!-- If you use a different primaryKey (e.g. email), adjust accordingly -->
<button wire:click='$emit(
"openSlideover",
"edit-user-slideover",
{{ json_encode(["user" => $user->email]) }})'
>Edit User</button>
<!-- Example of passing multiple parameters -->
<button wire:click='$emit(
"openSlideover",
"edit-user-slideover",
{{ json_encode([$user->id, $isAdmin]) }})'
>Edit User</button>
The parameters are passed to the mount
method on the slideover component:
<?php
namespace App\Http\Livewire;
use App\Models\User;
use LivewireUI\Slideover\SlideoverComponent;
class EditUserSlideover extends SlideoverComponent
{
public User $user;
public function mount(User $user)
{
Gate::authorize('update', $user);
$this->user = $user;
}
public function render()
{
return view('livewire.edit-user-slideover');
}
}
From an existing slideover you can use the exact same event and another slideover will stack onto the first:
<!-- Edit User Slideover -->
<!-- Edit Form -->
<button wire:click='$emit(
"openSlideover",
"delete-user-slideover",
{{ json_encode(["user" => $user->id]) }})'
>Delete User</button>
When you are done with the current slideover, you can close it by emitting the closeSlideover
event.
This will always close the most recent (in the foreground) slideover.
(N.B. at the moment, each time you close a slideover, the relative component's state will be destroyed).
<button wire:click="$emit('closeSlideover')">Close</button>
You can also close a slideover from within your slideover component class:
<?php
namespace App\Http\Livewire;
use App\Models\User;
use LivewireUI\Slideover\SlideoverComponent;
class EditUserSlideover extends SlideoverComponent
{
public User $user;
public function mount(User $user)
{
Gate::authorize('update', $user);
$this->user = $user;
}
public function update()
{
Gate::authorize('update', $user);
$this->user->update($data);
$this->closeSlideover();
}
public function render()
{
return view('livewire.edit-user-slideover');
}
}
You can change the width of the slideover in 2 ways.
(N.B. At the moment the width of the slideover is configurable by a CSS class, in this case a TailwindCSS one).
Declare this method inside your class.
Usefull when you know the slideover will always have the same width.
public static function slideoverWidth(): string
{
return 'w-11/12';
}
This approach is usefull when the slideover is opened on top of another slideover and you want to let the background one visible adapting the width of the new slidevoer in the foreground.
{{-- Blade View --}}
@php
$slideoverData = json_encode(['user' => $user->id]);
$slideoverAttributes = json_encode(['width' => 'w-8/12']);
@endphp
<button wire:click="$emit(
'openSlideover',
'delete-user-slideover',
{{ $slideoverData }}
{{ $slideoverAttributes }}"
>Delete User</button>
At the moment some feature of the wire-elements/modal
package are disabled:
- closing slideover with
escape
key - closing slideover by clicking outside of it (close on click away)
- dispatching events on slideover closing
- skipping previously opened slideover
This package can be used together with wire-elements/modal
. The recommended way is to declare it before the modal package, as follow:
<html>
<body>
<!-- content -->
@livewire('livewire-ui-slideover')
@livewire('livewire-ui-modal')
</body>
</html>
This will ensure that the modal element will always be on top of the slideover one.
Because of this joined usage the aformentioned capabilities of a slideover of closing on escape and on clickaway are disabled at the moment (they would have collide with the modal behavior).
E.g. If a modal is opened on top of a slideover, by pressing escape
both will be closed.
A future solution will be investigated.
You can (partially) customize the Slideover via the livewire-ui-slideover.php
config file.
(Actually only default width class).
To publish the config run the vendor:publish command:
php artisan vendor:publish --tag=livewire-ui-slideover-config
- complete example
- demo gif