maystro/filament-popup-modal
Adds popup-style modals to Filament, letting you open actions and forms in a lightweight overlay instead of navigating away. Useful for quick create/edit flows, confirmations, and compact UI interactions inside Filament panels.
Installation
composer require maystro/filament-popup-modal
Publish the config file:
php artisan vendor:publish --provider="Maystro\FilamentPopupModal\FilamentPopupModalServiceProvider"
Basic Usage Register the modal in your Filament resource/page:
use Maystro\FilamentPopupModal\Modal;
public function getModal(): Modal
{
return Modal::make('Confirm Action')
->content('Are you sure you want to proceed?')
->action('Confirm', fn() => $this->performAction())
->cancel('Cancel');
}
First Use Case Trigger the modal from a button in your Filament view:
<x-filament-actions::modal-button
action="getModal"
label="Delete Record"
icon="heroicon-o-trash"
/>
README.md for basic examples and API reference.config/filament-popup-modal.php for global settings like default animations or theme overrides.FilamentPopupModalServiceProvider for bootstrapping logic.Progress Bars Use for async operations (e.g., file uploads):
Modal::make('Uploading')
->progressBar()
->action('Upload', fn() => $this->uploadFiles())
->onProgressUpdated(fn(int $progress) => $this->updateProgress($progress));
Dynamic Content Pass data to the modal via closures:
Modal::make('Edit User')
->content(fn() => view('filament.modals.edit-user', ['user' => $this->record]))
->action('Save', fn() => $this->save());
Theme Integration Extend default themes (e.g., dark mode):
Modal::make('Theme Example')
->theme('dark')
->content('Custom dark-themed content');
Nested Modals Trigger a secondary modal from within another:
Modal::make('Primary Modal')
->action('Open Secondary', fn() => $this->getSecondaryModal());
getModals() in your resource/page class to register modals globally.public function mount()
{
$this->modal = Modal::make('Livewire Modal')
->action('Submit', fn() => $this->submitForm());
}
Modal::make('Create Record')
->form(YourForm::make())
->action('Create', fn() => $this->createRecord());
Modal Stacking
->closeAfterAction() to auto-close after actions:
Modal::make('Auto-Close')
->action('OK', fn() => $this->doSomething())
->closeAfterAction();
Progress Bar Stuck
onProgressUpdated is called periodically:
$this->emit('progress-updated', $progress); // If using Livewire
Theme Conflicts
->theme('custom') and override CSS in your assets:
.filament-popup-modal-theme-custom { ... }
Callback Delays
->deferAction() for delayed execution:
Modal::make('Deferred Action')
->action('Later', fn() => $this->deferAction())
->deferAction();
->onOpened()/->onClosed() for debugging:
Modal::make('Debug')
->onOpened(fn() => Log::info('Modal opened'))
->onClosed(fn() => Log::info('Modal closed'));
php artisan optimize:clear if modals fail to load.Custom Animations Override animations in the config:
'animations' => [
'open' => 'fadeIn',
'close' => 'fadeOut',
],
Modal Presets Create reusable presets in a trait:
trait UsesCustomModals
{
public function confirmDeleteModal(): Modal
{
return Modal::make('Delete')
->content('Are you sure?')
->action('Delete', fn() => $this->delete())
->cancel('Cancel');
}
}
Event Listeners Listen for modal events globally:
FilamentPopupModal::listen('modal.opened', fn(Modal $modal) => {
// Logic here
});
How can I help you explore Laravel packages today?