Search by

noerd / modal

noerd

Open each livewire component in a modal window.

Package info

github.com/noerd-dev/modal

pkg:composer/noerd/modal

Statistics

Installs: 2 652

Dependents: 1

Suggesters: 0

Stars: 5

Open Issues: 0

v0.3.30 2026-09-10 11:54 UTC

README

A stacked modal system for Laravel Livewire 4.
Open any Livewire component in a modal — no traits, no modifications to your livewire component code.

Modals can also be stacked — open another modal from inside an open one with the same $modal() call.

Stacked modals example

Installation

composer require noerd/modal

That is all — nothing needs to be published. The bundled JavaScript is served by the package itself through the route /noerd-modal/{file} (like Livewire serves livewire.js), so public/ stays untouched and the package works from vendor/ as well as from a path repository.

Add source path to your resources/css/app.css file

@source '../../vendor/noerd/modal/resources/views/**/*.blade.php';

Configuration

The config is merged automatically. Publish it only when you want to change the default panel position (center or right):

php artisan vendor:publish --tag=noerd-modal-config

Add Assets between your head tags.

<head>
...
<x-noerd::noerd-modal-assets/>
...
</head>

Add Modal Component to your layout. Make sure x-data is set on the body tag or any parent element of the modal component, otherwise the modal won't work.

<body x-data>
  <livewire:noerd-modal/>
...
</head>

Example Usage

Opening a Livewire component in a modal via a button

<button type="button"
    @click="$modal('livewire-component-name')">
    Open Modal
</button>

If you want to add parameters to your component which is opened in a modal:

<button type="button"
    @click="$modal('livewire-component-name', { name: 'John Doe' })">
    Open Modal
</button>
<?php

use Livewire\Component;

new class extends Component
{
    public string $name = ''; // will be set to John Doe
};
?>

<div class="p-4">
    {{$name}} {{-- Will display John Doe --}}
</div>

Stacked Modals

$modal(...) works the same way from inside an already-open modal — there is no extra API and no nesting limit. Calling it pushes a new modal onto the stack on top of the current one.

{{-- Inside a Livewire component that is itself open in a modal --}}
<button type="button"
    @click="$modal('another-livewire-component', { count: '{{ $count }}' })">
    Open another modal on top
</button>

Closing follows LIFO order:

  • ESC closes only the topmost modal.
  • Dispatch closeTopModal from PHP/Livewire to close the top modal programmatically.
  • Dispatch closeAllModals to clear the entire stack at once.

Layering is handled automatically: only the top modal is interactive; modals beneath it are dimmed and slightly scaled down — no styling work required on your end.

Developing the package

Run npm run dev inside the package directory: it writes the Vite hot file to public/vendor/noerd-modal/hot of the host application (the vite config assumes the package lives in app-modules/noerd-modal), and <x-noerd::noerd-modal-assets/> then loads the bundle from the dev server instead of the package route. npm run build writes the bundle to dist/build, which is committed and shipped with the package.

Publishing the Example

To publish the example components and a demo route, run:

php artisan noerd-modal:publish-example

This will:

  • Copy example components to resources/views/components/example/
  • Add a route /noerd-example-modal to routes/web.php

Example Livewire Starter Kit

If you are using the Livewire Starter Kit you can edit the sidebar.blade.php like this example to make noerd modal working

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
    <head>
        @include('partials.head')
        <x-noerd::noerd-modal-assets/>
    </head>
    <body x-data class="min-h-screen bg-white dark:bg-zinc-800">
        <livewire:noerd-modal/>