Modal
A modal is a versatile UI component that allows you to display important information, alerts, or prompts to users without requiring them to leave the current page. Typically containing a header, body, and footer, it can present anything from notifications to forms. Modals can be closed by the user, providing an intuitive way to deliver essential details or gather input while maintaining the flow of interaction.
Basic Usage
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel">
<p class="spr-text-center">This is a sample modal</p>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
Header
The header of a modal is used to display the title or heading, giving users context about the content inside. You can set the header in two ways:
- Using the title Prop: Pass a string to the title prop to quickly define the modal's header.
- Using Slots: Alternatively, you can customize the header by using a slot, giving you more flexibility to insert complex or dynamic content.
This flexibility allows you to tailor the modal's header to meet the needs of your specific application.
By using props title
:
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" title="Modal Header Props">
<p class="spr-text-center">This is a sample modal</p>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
By using slot
:
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel">
<template #header>Modal Header Slot</template>
<p class="spr-text-center">This is a sample modal</p>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
You can also force remove X
button from header by using props closeButtonX
:
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" :closeButtonX="false">
<template #header>Modal Header Slot</template>
<p class="spr-text-center">This is a sample modal</p>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
Footer
The footer of a modal can contain action buttons like "Cancel" or "Save," or it can simply display text. You can customize it using slots or props to provide clear actions or additional information to users.
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel">
<template #header>Modal Header Slot</template>
<p class="spr-text-center">This is a sample modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel = false">Close</spr-button>
</div>
</template>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
Set modal to active
To make the modal visible, bind the v-model
value to the modal's visibility state. By setting the v-model
value to true
, you trigger the modal to become active and display on the screen. This allows for dynamic control over the modal's visibility, enabling you to open and close it programmatically based on user interactions or other conditions within your application.
Disable Content Padding
You can control the content padding inside the modal by passing the contentPadding
prop. Set the value to true
to enable padding, or false
to disable it. This allows you to adjust the layout of the modal’s content, providing a more customized and visually appealing design based on your needs.
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" :contentPadding="false">
<template #header>Modal Header Slot</template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vehicula metus ut lectus tempor, ac volutpat
turpis malesuada. Suspendisse potenti. Sed efficitur mi non dui tincidunt, non venenatis lorem lacinia. Ut
scelerisque, mi nec egestas interdum, lorem ante volutpat enim, at volutpat purus purus ac magna. Nulla facilisi.
Integer fermentum neque sit amet sollicitudin suscipit. Integer scelerisque sapien a risus cursus, nec euismod
lacus faucibus. Etiam sed eros in velit egestas lobortis.
</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel = false">Close</spr-button>
</div>
</template>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
Sizes
Modals come in different sizes to suit various use cases. You can adjust the modal's size by using the size prop, which allows you to choose from the following options:
- Small (sm) (width: 360px - 480px): Best suited for simple content that doesn't require a lot of space, such as quick alerts or brief messages.
- Medium (md) (width: 480px - 720px): The default size, ideal for moderate content such as forms, additional text, or small forms.
- Large (lg) (width: 720px - 960px): Perfect for displaying more detailed content, such as forms with multiple fields, larger images, or more complex information.
- Extra Large (xl) (width: 900px - 1200px): Use for larger content like detailed forms, tables, or media-heavy information that requires a significant amount of space.
<template>
<div class="spr-flex spr-space-x-4">
<spr-button tone="success" @click="modalModel.small = true">Small (sm)</spr-button>
<spr-button tone="success" @click="modalModel.medium = true">Medium (md)</spr-button>
<spr-button tone="success" @click="modalModel.large = true">Large (lg)</spr-button>
<spr-button tone="success" @click="modalModel.extraLarge = true">Extra Large (xl)</spr-button>
</div>
<spr-modal v-model="modalModel.small" size="sm">
<template #header>Modal Header Slot</template>
<p class="!spr-m-0 spr-text-center">This is a sample small modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel.small = false">Close</spr-button>
</div>
</template>
</spr-modal>
<spr-modal v-model="modalModel.medium" size="md">
<template #header>Modal Header Slot</template>
<p class="!spr-m-0 spr-text-center">This is a sample medium modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel.medium = false">Close</spr-button>
</div>
</template>
</spr-modal>
<spr-modal v-model="modalModel.large" size="lg">
<template #header>Modal Header Slot</template>
<p class="!spr-m-0 spr-text-center">This is a sample large modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel.large = false">Close</spr-button>
</div>
</template>
</spr-modal>
<spr-modal v-model="modalModel.extraLarge" size="xl">
<template #header>Modal Header Slot</template>
<p class="!spr-m-0 spr-text-center">This is a sample extra large modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel.extraLarge = false">Close</spr-button>
</div>
</template>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref({
small: false,
medium: false,
large: false,
extraLarge: false,
});
</script>
Prevent Backdrop Close
To prevent the modal from closing when the user clicks on the backdrop (the area outside the modal), you can disable this behavior by setting the appropriate prop, such as staticBackdrop
to true
. This ensures that the modal remains open even if the user interacts with the backdrop, requiring explicit user actions (like clicking a close button) to close the modal.
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" staticBackdrop>
<template #header>Modal Header Slot</template>
<p class="spr-text-center">This is a sample modal</p>
<template #footer>
<div class="spr-flex spr-w-full spr-justify-end">
<spr-button tone="success" @click="modalModel = false">Close</spr-button>
</div>
</template>
</spr-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const modalModel = ref<boolean>(false);
</script>
API Reference
Props
Name | Description | Type | Default |
---|---|---|---|
modelValue | Controls the visibility of the modal. When true , the modal is displayed; when false , it is hidden. Used with v-model for two-way binding. | boolean | false |
title | Text to display in the modal header. This provides a straightforward way to add a title without using a slot. If both this prop and the header slot are used, the slot content takes precedence. | string | '' |
size | Determines the width of the modal dialog:
| 'sm' | 'md' | 'lg' | 'xl' | 'md' |
closeButtonX | When true , displays an X button in the top-right corner of the modal header that allows users to close the modal. Set to false to remove this button. | boolean | true |
contentPadding | Controls whether the modal content has padding. When true , adds standard padding to the content area; when false , removes padding, allowing content to extend to the edges of the modal. | boolean | true |
hasFooter | Controls whether the modal has a footer section. When true , reserves space for a footer section; when false , no footer area is rendered. | boolean | true |
staticBackdrop | When true , prevents the modal from closing when the user clicks on the backdrop (the area outside the modal). This is useful for modals that require explicit user actions to close. When enabled, clicking on the backdrop triggers a bounce animation to indicate the modal can't be closed this way. | boolean | false |
Events
Name | Description | Parameters |
---|---|---|
update:modelValue | Emitted when the modal visibility state changes. This event is used for v-model binding to work correctly. Triggered when the modal is closed via the X button or by clicking on the backdrop (when staticBackdrop is false ). | (value: boolean): The new visibility state of the modal. |
Slots
Name | Description |
---|---|
default | The main content area of the modal. Place your primary content here. Content will have padding by default (controlled by the contentPadding prop). |
header | Custom content for the modal header. This slot takes precedence over the title prop if both are provided. The header always includes the X close button unless closeButtonX is set to false . |
footer | Custom content for the modal footer. Typically contains action buttons such as "Cancel" or "Save". Only rendered when hasFooter is true . |