A Vuetify-styled drop-in replacement for @inertiaui/modal-vue. This package provides the same functionality as the original package but uses Vuetify components (v-dialog, v-card, v-btn) instead of Tailwind CSS for styling.
- âś… Drop-in replacement - Same API as
@inertiaui/modal-vue - âś… Vuetify 3 styling - Uses
v-dialog,v-card, and other Vuetify components - âś… Zero backend configuration - Works with existing Inertia.js routes
- âś… Modal and slideover support - Both dialog and drawer-style modals
- âś… Nested/stacked modals - Support for multiple modals
- âś… Local modals - Modals that don't require a route
- âś… Highly configurable - Customizable sizes, positions, and behavior
- âś… Full feature parity - All features from the original package
npm install @gigerit/inertia-modal-vuetify
# or
yarn add @gigerit/inertia-modal-vuetify
# or
pnpm add @gigerit/inertia-modal-vuetify
# or
bun add @gigerit/inertia-modal-vuetifyThis package requires the following peer dependencies:
vue^3.0.0vuetify^3.0.0@inertiajs/vue3^2.0.0@inertiaui/modal-vue(automatically installed as a dependency)
Make sure you have Vuetify installed and configured in your project:
npm install vuetify @mdi/fontUpdate your app.js (or main.js) to use the renderApp function:
import { createApp } from "vue";
import { createInertiaApp } from "@inertiajs/vue3";
import { renderApp } from "@gigerit/inertia-modal-vuetify"; // [!code ++]
createInertiaApp({
setup({ el, App, props, plugin }) {
return createApp({ render: renderApp(App, props) }) // [!code ++]
.use(plugin)
.mount(el);
},
});Replace Inertia's Link component with ModalLink to open routes in a modal:
<script setup>
import { ModalLink } from "@gigerit/inertia-modal-vuetify";
</script>
<template>
<ModalLink href="/users/create"> Create User </ModalLink>
</template>In your modal route/page, wrap the content with the Modal component:
<script setup>
import { Modal } from "@gigerit/inertia-modal-vuetify";
</script>
<template>
<Modal>
<h1>Create User</h1>
<form>
<!-- Form fields -->
</form>
</Modal>
</template>That's it! No backend changes needed.
<template>
<Modal>
<v-card>
<v-card-title>Modal Title</v-card-title>
<v-card-text> Modal content goes here </v-card-text>
</v-card>
</Modal>
</template><template>
<ModalLink href="/settings" slideover> Open Settings </ModalLink>
</template>
<!-- In your settings page -->
<template>
<Modal slideover>
<v-card class="h-100">
<v-card-title>Settings</v-card-title>
<v-card-text> Settings content </v-card-text>
</v-card>
</Modal>
</template><template>
<ModalLink href="/users/create" max-width="4xl"> Create User </ModalLink>
</template><template>
<div>
<ModalLink href="#confirm-action"> Delete Item </ModalLink>
<Modal name="confirm-action">
<v-card>
<v-card-title>Confirm Action</v-card-title>
<v-card-text> Are you sure you want to delete this item? </v-card-text>
<v-card-actions>
<v-btn @click="modal.close()">Cancel</v-btn>
<v-btn color="error" @click="deleteItem">Delete</v-btn>
</v-card-actions>
</v-card>
</Modal>
</div>
</template>
<script setup>
import { Modal, ModalLink, useModal } from "@gigerit/inertia-modal-vuetify";
const modal = useModal();
</script><script setup>
import { visitModal } from "@gigerit/inertia-modal-vuetify";
function openModal() {
visitModal("/users/create", {
config: {
maxWidth: "lg",
closeButton: true,
},
onClose: () => {
console.log("Modal closed");
},
});
}
</script>
<template>
<v-btn @click="openModal">Open Modal</v-btn>
</template>Both Modal and ModalLink components accept the following props:
| Prop | Type | Default | Description |
|---|---|---|---|
close-button |
Boolean | true |
Show/hide the close button |
close-explicitly |
Boolean | false |
Only close via button or programmatically |
max-width |
String | '2xl' |
Maximum width (sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl) |
padding-classes |
String/Boolean | 'pa-4 pa-sm-6' |
Vuetify padding classes |
panel-classes |
String/Boolean | '' |
Additional classes for the panel |
position |
String | 'center' |
Position (top, center, bottom for modals; left, right for slideovers) |
slideover |
Boolean | false |
Render as slideover instead of modal |
You can set default configuration for all modals:
import { putConfig } from "@gigerit/inertia-modal-vuetify";
putConfig({
modal: {
closeButton: true,
closeExplicitly: false,
maxWidth: "2xl",
paddingClasses: "pa-4 pa-sm-6",
panelClasses: "",
position: "center",
},
slideover: {
closeButton: true,
closeExplicitly: false,
maxWidth: "md",
paddingClasses: "pa-4 pa-sm-6",
panelClasses: "",
position: "right",
},
});Or update individual settings:
putConfig("modal.maxWidth", "lg");
putConfig("modal.closeButton", false);The main modal component that wraps your content.
Props: See Configuration section above.
Events:
@close- Emitted when modal is closed@focus- Emitted when modal gains focus@blur- Emitted when modal loses focus@success- Emitted when modal is successfully opened@after-leave- Emitted after modal is removed from DOM
Methods (via ref):
close()- Close the modalreload()- Reload modal propssetOpen(boolean)- Set open state
A link component that opens routes in a modal.
Props:
href(String, required) - The route to openmethod(String) - HTTP method (default:'get')data(Object) - Data to send with requestheaders(Object) - Additional headers- All modal configuration props
Events:
@start- Emitted when request starts@success- Emitted when modal opens successfully@error- Emitted on error@close- Emitted when modal closes@after-leave- Emitted after modal is removed
Access modal context and methods in child components:
<script setup>
import { useModal } from "@gigerit/inertia-modal-vuetify";
const { close, reload, props, config } = useModal();
</script>Programmatically open a modal:
import { visitModal } from "@gigerit/inertia-modal-vuetify";
visitModal("/users/create", {
method: "post",
data: { name: "John" },
config: {
maxWidth: "lg",
},
onClose: () => console.log("Closed"),
});getConfig(key)- Get configuration valueputConfig(key, value)- Set configuration valueresetConfig()- Reset to defaults
This package uses Vuetify components, so all styling is handled through Vuetify's theming system. You can customize:
- Colors - Use Vuetify theme colors
- Spacing - Use Vuetify spacing utilities (
pa-4,ma-2, etc.) - Elevation - Cards use Vuetify's elevation system
- Typography - Inherits from your Vuetify theme
You can still apply custom classes via the panel-classes and padding-classes props:
<Modal panel-classes="bg-blue-grey-darken-1" padding-classes="pa-8">
<!-- Content -->
</Modal>This package is designed as a drop-in replacement. Simply:
-
Replace the import:
// Before import { Modal, ModalLink } from "@inertiaui/modal-vue"; // After import { Modal, ModalLink } from "@gigerit/inertia-modal-vuetify";
-
Remove Tailwind CSS configuration (if not used elsewhere)
-
Ensure Vuetify is installed and configured
That's it! The API is identical, so no code changes are needed.
An example application is included in the example/ directory. To run it:
# Install dependencies
bun install
# Run the example
bun run devVisit http://localhost:3000 to see various modal examples in action.
The main differences are:
- Styling - Uses Vuetify components instead of Tailwind CSS
- No Tailwind required - Pure Vuetify styling
- Vuetify theming - Respects your Vuetify theme configuration
- Material Design Icons - Close button uses
mdi-closeicon
All functionality, API, and behavior remain the same.
Supports all browsers that Vuetify 3 supports. See Vuetify Browser Support.
To build the package locally:
npm run buildThis will create the dist/ directory with:
inertia-modal-vuetify.es.js- ES module buildinertia-modal-vuetify.cjs.js- CommonJS buildindex.d.ts- TypeScript definitions
The package is automatically built before publishing via the prepublishOnly script.
To run the example app:
npm run devThis starts the Vite dev server for the example application.
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit using conventional commits (e.g.,
feat: add new feature) - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project uses Conventional Commits for automated versioning:
MIT
- @inertiaui/modal-vue - Original Tailwind-styled version
- Inertia.js - The underlying framework
- Vuetify - The UI framework used for styling
Contributions are welcome! Please feel free to submit a Pull Request.
For issues related to:
- Modal functionality - See @inertiaui/modal-vue documentation
- Vuetify styling - See Vuetify documentation
- This package - Open an issue on GitHub