Modal window with Livewire 3 + Alpinejs with Bootstrap, Tailwind
👉 For Backend Coding Enjoyers 😉
Create modal dialog easily with laravel project with livewire 3 + Alpinejs & manage modal dialog as livewire component.
Still on beta version
composer require larawire-garage/larawire-modals
php artisan vendor:publish --tag=larawire-modals-configs
Currently supports 2 themes.
You can use CDN Link to apply bootstrap.
If you are using package managers like npm
use Bootstrap Documentation to install.
When Importing Bootstrap add below code to app.js
file.
// Import all of Bootstrap's JS
import * as bootstrap from 'bootstrap'
window.bootstrap = bootstrap; // 👈 required
You can use CDN Link to apply Tailwindcss.
If you are using package managers like npm
use Tailwindcss Documentation to install. Then Add below code to tailwind.config.js
file.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
"./vendor/larawire-garage/larawire-modals/**/*.blade.php", // 👈 Add this line
],
//...
}
If not working correctly? Check Here
You can add theme your proejct used in larawire-modals
config file.
// configs/larawire-modals.php
return [
'theme' => 'bootstrap',
// OR
'theme' => 'tailwind',
// ....
];
Also you can change theme in your modal variable inside the modal component.
// app/Livewire/MODAL_PATH/MYMODAL.php
class MYMODAL extends ModalComponent{
public array $modal = [
'theme' => 'bootstrap',
// OR
'theme' => 'tailwind',
//...
];
}
create modal component using below command.
php artisan make:modal MyModal
Now you can use modal component like regular livewire component. By default this command create component:
Class
: app/Livewire/ModalsView
: resources/views/livewire/modalsdirectories. You can change it in the larawire-modals
config file.
// configs/larawire-modals.php
return [
'class_namespace' => 'App\\Livewire\\Modals',
'view_path' => resource_path('views/livewire/modals'),
// ....
];
$this->dispatch('show')->to(MyModal::class);
$this->dispatch('close')->to(MyModal::class);
$this->dispatch('close')->self();
//or
$this->closeModal();
Modal component has $modal
public variable containing modal options.
public array $modal = [
'id' => 'my-modal',
'title' => 'My Modal',
//...
];
id
- Modal IDtitle
- Modal title text on the headertheme
- Theme using in the project (bootstrap or tailwind). Can be defind in the larawire-modals config fileresetBeforeShow
- if this is true, public variables in the modal component automatically reset before show the modal. Can be defind in the larawire-modals config fileresetValidationBeforeShow
- if this is true, Reset the validation error bag of modal component automatically before show the modal. Can be defind in the larawire-modals config fileshowModal()
- Show the modal dialogcloseModal()
- Close the modal dialogYou can define:
beforeShow()
- Runs before show the modal dialogbeforeClose()
- Runs before close the modal dialogIf your modal contains form, add formSubmit attribute to modal component.
When formSubmit
attribute defined, modal body
and footer
slots automatically covered by form tag with wire:submit="[form-submit-value]"
attribute.
<x-larawire::modal :modal="$modal" formSubmit="createNewUser">
<!-- 👆 Add form submit parameter here -->
<x-slot name="body">
<!-- Modal body content -->
<!-- Add form content here -->
<input type="text" class="" name="name" id="name-input" wire:model="name">
</x-slot>
<x-slot name="footer" :defaultClose="true">
<!-- Modal footer content -->
<!-- 👇 Add button for submit the form -->
<button type="submit" wire:loading.attr="disabled" wire:target='createNewUser'>
<span wire:loading.class="d-none hidden">Create</span>
<span wire:loading wire:target="createNewUser">Creating...</span>
</button>
</x-slot>
</x-larawire::modal>
In the larawire-modals config file you can change classes of the containers of the modal. Also can change in the modal variable of the modal component.
// configs/larawire-modals.php
return [
// ...
'theme-classes' => [
'bootstrap' => [
'backdropClasses' => '',
'containerClasses' => '',
'windowClasses' => '',
'headerClasses' => '',
'headerCloseBtnClasses' => '',
'bodyClasses' => '',
'footerClasses' => '',
'footerCloseBtnClasses' => '',
],
'tailwind' => [
'backdropClasses' => '',
'containerClasses' => '',
'windowClasses' => '',
'headerClasses' => '',
'headerCloseBtnClasses' => '',
'bodyClasses' => '',
'footerClasses' => '',
'footerCloseBtnClasses' => '',
],
],
];
// app/Livewire/MODAL_PATH/MYMODAL.php
class MYMODAL extends ModalComponent{
public array $modal = [
/** available if needs to customize */
'backdropClasses' => '',
'containerClasses' => '',
'windowClasses' => '',
'headerClasses' => '',
'headerCloseBtnClasses' => '',
'bodyClasses' => '',
'footerClasses' => '',
'footerCloseBtnClasses' => '',
//...
];
}
Changing classes still not working for you ? To customize appearance of the modal, you can publish the views and edit it.
php artisan vendor:publish --tag=larawire-modals-views
Also you can change animation of the modal.
Bootstrap Theme
:
In bootstrap, follow bootstrap documentation to change the modal animation.
Tailwind Theme
:
In tailwind theme under animation
key in them larawire-modals config file.
Also you can change it in the modal variable in the modal component.
// app/Livewire/MODAL_PATH/MYMODAL.php
class MYMODAL extends ModalComponent{
public array $modal = [
/** Only for tailwind */
'animation' => 'slide-down', // <== slide-down, scale-up
//...
];
}
For deep customize animation classes check under animation-classes
key in larawire-modals config file.
In Tailwind theme, modal use alpinejs & tailwindcss animation classes to animate modals.
In case modal not working correctly, Eg:
Add below array of classes to safelist
array
If you change the classes in config file or in class modal variable, that classes also need to include here
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
"./vendor/larawire-garage/larawire-modals/**/*.blade.php", // 👈 Add this line
],
/**
* ⚠️⚠️⚠️ If in-case (content path) 👆 not working.⚠️⚠️⚠️
* 👇 Add this block
*/
safelist: [
'backdrop-blur-sm',
'bg-white', 'bg-gray-400', 'bg-gray-800/30', 'bg-red-300',
'border', 'border-b', 'border-t',
'dark:bg-gray-900', 'dark:text-gray-100',
'duration-200', 'duration-300',
'ease-in', 'ease-out',
'fixed', 'inset-0',
'flex', 'flex-none', 'grow', 'items-center', 'justify-between', 'self-end',
'font-bold',
'h-fit', 'h-screen',
'hover:bg-gray-800', 'hover:text-gray-100', 'hover:text-red-600',
'opacity-0', 'opacity-100',
'overflow-y-auto', 'overflow-y-hidden',
'p-5', 'px-2', 'px-5', 'py-1', 'py-2', 'py-3', 'md:p-14',
'rounded-b-lg', 'rounded-lg', 'rounded-t-lg',
'sm:scale-100', 'sm:scale-95',
'text-3xl', 'text-black', 'text-end', 'text-gray-900',
'transform',
'transition', 'transition-all',
'translate-y-0', 'translate-y-4', 'sm:translate-y-0', '-translate-y-8',
'w-full', 'w-3/5',
'z-50',
]
//...
}
!!! 🎉🎉🎉 Enjoy 🎉🎉🎉 !!!