Skip to content

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

vue
<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>

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:
vue
<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:
vue
<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:
vue
<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>

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.

vue
<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.

vue
<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.
vue
<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.

vue
<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

NameDescriptionTypeDefault
modelValueControls the visibility of the modal. When true, the modal is displayed; when false, it is hidden. Used with v-model for two-way binding.booleanfalse
titleText 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: Small size (360px - 480px) - Good for alerts or brief messages
  • md: Medium size (480px - 720px) - Default size, suitable for forms and moderate content
  • lg: Large size (720px - 960px) - For detailed forms or complex information
  • xl: Extra large size (900px - 1200px) - For extensive content or media-heavy information
'sm' | 'md' | 'lg' | 'xl''md'
closeButtonXWhen 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.booleantrue
contentPaddingControls 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.booleantrue
hasFooterControls whether the modal has a footer section. When true, reserves space for a footer section; when false, no footer area is rendered.booleantrue
staticBackdropWhen 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.booleanfalse

Events

NameDescriptionParameters
update:modelValueEmitted 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

NameDescription
defaultThe main content area of the modal. Place your primary content here. Content will have padding by default (controlled by the contentPadding prop).
headerCustom 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.
footerCustom content for the modal footer. Typically contains action buttons such as "Cancel" or "Save". Only rendered when hasFooter is true.

Product Uses

Sprout HR
Sprout Ecosystem
Sprout Sidekick