laravelcm/livewire-slide-overs
Livewire slide-over drawer panel for Laravel. Open slide-overs via events, stack multiple child components, and preserve state—modal-like behavior inspired by wire-elements/modal, but as a drawer. Supports PHP 8.3+, Laravel 11/12, Livewire 3.4/4.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require laravelcm/livewire-slide-overs
Publish the config (if needed) with:
php artisan vendor:publish --provider="Laravelcm\LivewireSlideOvers\SlideOverServiceProvider"
Basic Usage: Add the root component to your layout:
@livewire('slide-over-panel')
Trigger a slide-over instantly with:
<!-- Instant open (no animation) -->
<button wire:click="$emit('slideOverOpenInstant', 'unique-id')">Open Instantly</button>
<!-- Standard open (with animation) -->
<button wire:click="$emit('slideOverOpen', 'unique-id')">Open with Animation</button>
First Slide-Over: Define a slide-over in your Blade template with optional dynamic resize:
<livewire:slide-over-panel.child
id="unique-id"
title="My Slide Over"
:open="false"
:resizable="true" <!-- New: Enable dynamic resizing -->
:native-dialog="true" <!-- New: Native browser dialog mode -->
>
<!-- Slide-over content -->
<p>This is my slide-over content.</p>
</livewire:slide-over-panel.child>
Component Hierarchy:
@livewire('slide-over-panel') (manages state, animations, and new features like native-dialog).<livewire:slide-over-panel.child> (individual slide-overs with optional resizable and native-dialog props).$emit('slideOverOpen', 'id') → Standard animated open.$emit('slideOverOpenInstant', 'id') → New: Instant open (no animation).$emit('slideOverClose', 'id') → Close slide-over.Dynamic Slide-Overs with New Features: Dynamically register slide-overs with enhanced options:
public $slideOvers = [
'id-1' => [
'title' => 'Dynamic Title',
'content' => '<p>Dynamic content</p>',
'resizable' => true, // New: Enable resizing
'native_dialog' => false, // New: Use native dialog mode
],
'id-2' => [
'title' => 'Native Dialog',
'content' => '<p>Uses browser dialog</p>',
'native_dialog' => true, // New: Native dialog mode
],
];
Render them in Blade:
@foreach($slideOvers as $id => $slideOver)
<livewire:slide-over-panel.child
id="{{ $id }}"
title="{{ $slideOver['title'] }}"
:open="false"
:resizable="{{ $slideOver['resizable'] ?? false }}"
:native-dialog="{{ $slideOver['native_dialog'] ?? false }}"
>
{!! $slideOver['content'] !!}
</livewire:slide-over-panel.child>
@endforeach
State Management:
wire:model to bind slide-over state to Livewire properties:
<livewire:slide-over-panel.child
id="my-id"
wire:model="isOpen"
:native-dialog="true"
>
$this->slideOverStates in your Livewire class.native_dialog mode in your logic:
if ($this->slideOverStates['my-id']['native_dialog']) {
// Handle native dialog behavior
}
Native Dialog Mode:
role="dialog").<livewire:slide-over-panel.child
id="confirmation-dialog"
title="Confirm Action"
:native-dialog="true"
>
<p>Are you sure you want to proceed?</p>
</livewire:slide-over-panel.child>
Dynamic Resizing:
<livewire:slide-over-panel.child
id="resizable-panel"
:resizable="true"
>
<div class="h-[300px] overflow-auto"> <!-- Content with scrollable area -->
<!-- Resize handle (auto-injected by package) -->
</div>
</livewire:slide-over-panel.child>
Custom Animations for New Modes:
Extend the child component to customize animations for native-dialog or resizable slide-overs:
class CustomNativeDialog extends SlideOverPanelChild
{
public function slideOverAnimation()
{
return 'transition ease-out duration-200';
}
public function slideOverClass()
{
return parent::slideOverClass() . ' backdrop-blur-sm';
}
}
ID Collisions:
user-profile-settings, cart-sidebar).Native Dialog Quirks:
native-dialog="true") may behave differently across browsers (e.g., focus trapping, scroll locking)..slide-over-panel.native-dialog {
backdrop-filter: blur(5px);
}
Resizable Slide-Overs:
<livewire:slide-over-panel.child id="static-panel" :resizable="false" />
.slide-over-panel.resizable .resize-handle {
right: 2px;
top: 0;
width: 5px;
background: #333;
}
Instant Open vs. Standard Open:
Livewire 3 vs. 4:
$emit vs. $dispatch).$emit('slideOverOpenInstant'). Ensure your listeners are updated:
protected $listeners = [
'slideOverOpenInstant.*' => 'handleInstantOpen',
];
Z-Index Conflicts:
z-index stack. Native dialogs may require higher z-index values.z-index in the published config or override it in your CSS:
.slide-over-panel.native-dialog {
z-index: 6000 !important;
}
Inspect State: Add this to your root component to debug slide-over states (including new props):
public function render()
{
dd($this->slideOverStates); // Check for 'resizable' and 'native_dialog' keys
return view('livewire.slide-over-panel');
}
Check for JavaScript Errors:
dialog elements (modern browsers only). Fallback gracefully:
@if (config('slide-over.native_dialog_fallback', false))
<div class="fallback-dialog">...</div>
@endif
window.Alpine undefined).How can I help you explore Laravel packages today?