moonlydays/inertia-routed-modals

Use your routes to open modal windows the same way you open pages with Inertia

Fund package maintenance!
Daniel Basiuc-Brinzei

Installs: 10

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 1

Forks: 0

Open Issues: 0

Language:TypeScript

1.1.0 2024-12-16 19:06 UTC

This package is auto-updated.

Last update: 2024-12-16 19:08:53 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Note

This package supports React only.

Installation

You can install the package via composer:

composer require moonlydays/inertia-routed-modals

Install the npm package using:

npm install vendor/moonlydays/inertia-routed-modals/node/react

Inside the HandleInertiaRequest middleware in your app, add the following:

use MoonlyDays\InertiaRoutedModals\SharesRoutedModals;

class HandleInertiaRequests extends Middleware
{
    use SharesRoutedModals; // add this

    public function share(Request $request): array
    {
        return [
            ...parent::share($request),
            ...$this->shareModal(), // add this
            // ...
        ];
    }
}

Usage

Backend

It all starts with a route. Inside your controller create an action that will return the modal using the new Inertia::modal method. The first argument is the modal component name (relative to Modals folder). The second optional argument is an array of props that have to be passed to the modal.

public function action()
{
    return Inertia::modal("Component", [
        "prop" => "value",
        "other" => "value"
    ]);
}

Frontend

Inside your app.tsx wrap the App component with RoutedModalsProvider component. Use may the same function resolvePageComponent that use used to resolve Inertia pages to resolve modal components.

import {RoutedModalsProvider} from "./RoutedModalsProvider";

createInertiaApp({
    // ...
    setup({el, App, props}) {
        const root = createRoot(el);

        root.render(
            <RoutedModalsProvider
                resolve={(name) =>
                    resolvePageComponent(
                        `./Modals/${name}.tsx`,
                        import.meta.glob('./Modals/**/*.tsx'),
                    )
                }
            >
                <App {...props} />
            </RoutedModalsProvider>,
        );
    }
})

Next you have to specify where the Modal components will be mounted in your layout. Use <ModalPortal /> somewhere in the root of your page layout to set that.

import {ModalPortal} from "./ModalPortal";

export function MainLayout({children}) {

    return (
        <div className="bg-black">
            {children}
            <ModalPortal/>
        </div>
    );

}

Create a new resources/js/Modals folder and create a new modal component the same way you create Inertia pages. The modal components are headless, meaning they are mounted to the DOM without any overhead elements. This is an example MyModal component:

// resources/js/Modals/MyModal.tsx
export default function MyModal() {
    return (
        <div className="absolute w-full h-full bg-black/50 z-50 flex items-center justify-center">
            <div>This is a cool looking Modal!</div>
        </div>
    );
}

Now to open that modal, create a <Link ... /> somewhere in your app that leads to your route that returns a modal. When that Link will be clicked your modal will be opened.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.