{"id":25323999,"url":"https://github.com/emargareten/inertia-modal","last_synced_at":"2025-04-13T02:11:39.736Z","repository":{"id":71544939,"uuid":"591943175","full_name":"emargareten/inertia-modal","owner":"emargareten","description":"Implement backend-driven modal dialogs for Laravel+Inertia apps.","archived":false,"fork":false,"pushed_at":"2025-02-24T10:51:26.000Z","size":204,"stargazers_count":77,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-04T05:04:02.067Z","etag":null,"topics":["inertiajs","laravel","modals"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emargareten.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-22T12:39:02.000Z","updated_at":"2025-03-22T22:40:33.000Z","dependencies_parsed_at":"2024-03-12T19:57:25.321Z","dependency_job_id":"aac64e19-e349-4bbc-9c1a-2c4c8d49018f","html_url":"https://github.com/emargareten/inertia-modal","commit_stats":{"total_commits":41,"total_committers":5,"mean_commits":8.2,"dds":"0.46341463414634143","last_synced_commit":"b305ef15e59c785ff8cd835e1f30b6abdca8da0f"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emargareten%2Finertia-modal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emargareten%2Finertia-modal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emargareten%2Finertia-modal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emargareten%2Finertia-modal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emargareten","download_url":"https://codeload.github.com/emargareten/inertia-modal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654089,"owners_count":21140236,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["inertiajs","laravel","modals"],"created_at":"2025-02-14T00:55:20.828Z","updated_at":"2025-04-13T02:11:39.703Z","avatar_url":"https://github.com/emargareten.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inertia Modal\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/emargareten/inertia-modal.svg?style=flat-square)](https://packagist.org/packages/emargareten/inertia-modal)\n[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/emargareten/inertia-modal/run-tests.yml?branch=master\u0026label=tests\u0026style=flat-square)](https://github.com/emargareten/inertia-modal/actions?query=workflow%3Arun-tests+branch%3Amaster)\n[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/emargareten/inertia-modal/fix-php-code-style-issues.yml?branch=master\u0026label=code%20style\u0026style=flat-square)](https://github.com/emargareten/inertia-modal/actions?query=workflow%3A\"Fix+PHP+code+style+issues\"+branch%3Amaster)\n[![Total Downloads](https://img.shields.io/packagist/dt/emargareten/inertia-modal.svg?style=flat-square)](https://packagist.org/packages/emargareten/inertia-modal)\n\nInertia Modal is a Laravel package that lets you implement backend-driven modal dialogs for Inertia apps. With this package, you can define modal routes on the backend and dynamically render them when you visit a dialog route.\n\n\u003e [!NOTE]\n\u003e This package supports Vue 3 only\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require emargareten/inertia-modal\n```\n## Frontend Setup\n\n\u003e [!WARNING]\n\u003e The package utilizes `axios` under the hood. If your app is already using `axios` as a dependency, make sure to lock it to the same version Inertia uses.\n\n### `Modal` Component\n\nModal is a **headless** component, meaning you have full control over its look, whether it's a modal dialog or a slide-over panel. You are free to use any 3rd-party solutions to power your modals, such as [Headless UI](https://github.com/tailwindlabs/headlessui).\n\nPut the `Modal` component somewhere within the layout.\n\n```vue\n\u003cscript setup\u003e\nimport { Modal } from '../../vendor/emargareten/inertia-modal'\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003c!-- layout --\u003e\n    \u003cModal /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n\u003e [!NOTE]\n\u003e Ensure that the layout remains [persistent](https://inertiajs.com/pages#persistent-layouts) throughout the entire application. If you have multiple layouts, create a base layout that should invoke the modal, using nested layouts.\n\n### Plugin\n\nSet up a `modal` plugin with the same component resolver you use to render Inertia pages.\n\n#### Vite\n\n```javascript\nimport { modal } from '../../vendor/emargareten/inertia-modal'\n\ncreateInertiaApp({\n  resolve: (name) =\u003e resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')),\n  setup({ el, app, props, plugin }) {\n    createApp({ render: () =\u003e h(app, props) })\n      .use(modal, {\n        resolve: (name) =\u003e resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')),\n      })\n      .use(plugin)\n      .mount(el)\n  }\n})\n```\n\n#### Laravel Mix\n\n```javascript\nimport { modal } from '../../vendor/emargareten/inertia-modal'\n\ncreateInertiaApp({\n  resolve: (name) =\u003e require(`./Pages/${name}`),\n  setup({ el, App, props, plugin }) {\n    createApp({ render: () =\u003e h(App, props) })\n      .use(modal, {\n        resolve: (name) =\u003e import(`./Pages/${name}`),\n      })\n      .use(plugin)\n      .mount(el)\n  }\n})\n```\n\n## Usage\n\nModals have their own routes, letting you access them even via direct URLs. Define routes for your modal pages.\n\n```php\n// background context / base page\nRoute::get('users', [UserController::class, 'index'])-\u003ename('users.index');\n\n// modal route\nRoute::get('users/{user}', [UserController::class, 'show'])-\u003ename('users.show');\n```\n\nRender a modal from a controller. Specify the `base` route to render the background when the modal is accessed directly.\n\n```php\nuse Emargareten\\InertiaModal\\Modal;\nuse Inertia\\Inertia;\n\nclass UserController extends Controller\n{\n    // ...\n    \n    public function show(User $user): Modal\n    {\n        return Inertia::modal('Users/Show', ['user' =\u003e $user])-\u003ebaseRoute('users.index');\n    }\n}\n```\n\nBy default, the backdrop component will be preserved with its current [stale] data (besides for the validation errors), in most cases this is fine since it\nwill refresh when we close the modal (redirect to the base route), if your app does need fresh data for the backdrop, add\nthe `refreshBackdrop` method:\n\n```php\n    public function show(User $user): Modal\n    {\n        return Inertia::modal('Users/Show', ['user' =\u003e $user])\n            -\u003ebaseRoute('users.index')\n            -\u003erefreshBackdrop();\n    }\n```\n\nTo force a specific route as the backdrop add the `forceBase` method:\n\n```php\n    public function show(User $user): Modal\n    {\n        return Inertia::modal('Users/Show', ['user' =\u003e $user])\n            -\u003ebaseRoute('users.index')\n            -\u003eforceBase();\n    }\n```\n\nThis will force re-render of the base route (or even redirect to a different base route).\n\nBoth of the above methods can also accept a boolean whether to refresh etc.\n\n### Frontend implementation\n\nUse the `useModal()` composable in your modal component.\n\nThis example is a simple headlessui modal, you can add more transitions etc. see https://headlessui.com/vue/dialog.\n\n```vue\n\u003ctemplate\u003e\n  \u003cTransitionRoot appear as=\"template\" :show=\"show\"\u003e\n    \u003cDialog as=\"div\" class=\"relative z-10\" @close=\"close\"\u003e\n      \u003cTransitionChild @after-leave=\"redirect\" as=\"template\"\u003e\n        \u003cdiv class=\"fixed inset-0 bg-black/75 transition-opacity\" /\u003e\n      \u003c/TransitionChild\u003e\n\n      \u003cdiv class=\"fixed inset-0 overflow-y-auto\"\u003e\n        \u003cdiv class=\"flex min-h-full items-center justify-center p-4 text-center\"\u003e\n          \u003cTransitionChild as=\"template\"\u003e\n            \u003cDialogPanel class=\"w-full max-w-lg transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all\"\u003e\n              \u003cDialogTitle as=\"h3\" class=\"text-lg font-medium leading-6 text-gray-900\"\u003e\n                \u003cslot name=\"title\" /\u003e\n              \u003c/DialogTitle\u003e\n              \u003cslot /\u003e\n            \u003c/DialogPanel\u003e\n          \u003c/TransitionChild\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    \u003c/Dialog\u003e\n  \u003c/TransitionRoot\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { TransitionRoot, TransitionChild, Dialog, DialogPanel, DialogTitle } from '@headlessui/vue'\nimport { useModal } from '../../vendor/emargareten/inertia-modal'\n\nconst { show, close, redirect } = useModal()\n\u003c/script\u003e\n```\n\nThe `redirect` method will redirect to the base route, you can pass in all inertia visit options as a parameter.\n\n```javascript\nredirect({ preserveScroll: true })\n```\n\nThe `close` method will close the modal without redirecting to the base route.\n\n\u003e [!NOTE]\n\u003e For a more concise setup, consider configuring aliases instead of specifying the full path.\n\u003e\n\u003e Using vite:\n\u003e ```js\n\u003e // vite.config.js\n\u003e export default defineConfig({\n\u003e   resolve: {\n\u003e     alias: {\n\u003e       'inertia-modal': path.resolve('vendor/emargareten/inertia-modal'),\n\u003e     },\n\u003e   },\n\u003e });\n\u003e ```\n\u003e\n\u003e Using mix:\n\u003e ```js\n\u003e // webpack.mix.js\n\u003e mix.alias({\n\u003e   'inertia-modal': path.resolve('vendor/emargareten/inertia-modal'),\n\u003e });\n\u003e ```\n\u003e \n\u003e Now you can import the modules like this:\n\u003e ```js\n\u003e import { useModal } from 'inertia-modal'\n\u003e ```\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Security Vulnerabilities\n\nPlease review [our security policy](../../security/policy) on how to report security vulnerabilities.\n\n## Credits\n\nThis package was highly inspired by [momentum-modal](https://github.com/lepikhinb/momentum-modal)\n\n- [emargareten](https://github.com/emargareten)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femargareten%2Finertia-modal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femargareten%2Finertia-modal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femargareten%2Finertia-modal/lists"}