Skip to content

Modal

Base component for modal dialog.

Usage

Modal are using z-modal for z-index value. It posible to change z-index value using CSS variable --p-modal-z-index. But don't forget to see the all z-index variant for layer-ordering component.

Simple Usage

preview
vue
<template>
  <p-modal v-model="showModal"
    title="Modal Title"
    text="This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information.">
    <template #footer="{ close }">
      <div class="flex items-center justify-end">
        <p-button @click="close" color="info">
          Submit
        </p-button>
      </div>
    </template>
  </p-modal>
</template>

Combine with additional component

preview
vue
<template>
  <p-modal
    v-model="advanceModal"
    title="Modal Title">
    <p>
      This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information.
    </p>
    <p-banner>
      Your enterprise Privy Balance is running out. Please topup now.
    </p-banner>
    <template #footer="{ close }">
      <div class="flex items-center justify-between">
        <div>
          <p-checkbox>
            This is additional checbox for the modal
          </p-checkbox>
        </div>
        <div>
          <p-button @click="close" color="info">
            Button text
          </p-button>
        </div>
      </div>
    </template>
  </p-modal>
</template>

Hide close button

You can hide close button with dismissable set to false

preview
vue
<template>
  <p-modal
    title="Give Me Title Here"
    v-model="bottomSheet"
    :dismissable="false">
    <p>
      Explain what this menu to do, <br>
      descriptive but as short as possible
    </p>
    <template #footer>
      <div class="flex justify-end">
        <p-button color="info" @click="bottomSheet = false">
          Button Text
        </p-button>
      </div>
    </template>
  </p-modal>
</template>

No Close Modal

Modal will not close while Escape button was pressed by props no-close-on-esc. Also you can make modal can't close while backdrop was clicked by props no-close-on-backdrop.

preview
vue
<template>
  <p-modal
    title="Modal Title"
    no-close-on-esc
    no-close-on-backdrop
    v-model="bannerSheet" :dismissable="false">
    <p>
      This is place holder text. <br>
      The basic dialog for modals should <br>
      contain only valuable and relevant information.
    </p>
    <template #footer="{ close }">
      <div class="flex justify-end">
        <p-button color="info" @click="close">
          Button Text
        </p-button>
      </div>
    </template>
  </p-modal>
</template>

When modals content become too long, modal body can scroll itself by adding props modal-body-scrollable.

preview
vue
<template>
  <p-modal
    v-model="scrollModal"
    title="Modal Title"
    no-close-on-esc
    no-close-on-backdrop
    modal-body-scrollable>
    <div>
      <p>
        This is place holder text. The basic dialog for modals should contain only valuable and relevant information. Simplify dialogs by removing unnecessary elements or content that does not support user tasks. If you find that the number of required elements for your design are making the dialog excessively large, then try a different design solution.
      </p>
      <blockquote>
        A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart.
      </blockquote>
      <p>
        I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine. I am so happy, my dear friend, so absorbed in the exquisite sense of mere tranquil existence, that I neglect my talents.
      </p>
    </div>
    <template #footer="{ close }">
      <p-button @click="close" color="info">
        Button Text
      </p-button>
    </template>
  </p-modal>
</template>

Modal can be set look like banner with prop banner. For example, it can be used for promotional purposes, events and others.

vue
<template>
  <p-modal
    v-model="modalBanner"
    :dismissable="false"
    banner>
    <img src="/assets/images/img-modal-banner-sheet.jpg">
    <div class="p-6 text-center">
      <p-heading element="h6">Give Me Title Here</p-heading>
      <p>
        Explain what this menu to do, <br>
        descriptive but as short as possible
      </p>
    </div>
    <template #footer="{ close }">
      <div class="flex items-center justify-end">
        <p-button variant="link" @click="close">
          Button Text
        </p-button>
        <p-button color="info" @click="close">
          Button Text
        </p-button>
      </div>
    </template>
  </p-modal>
</template>

Sizing

Modal has 5 different sizing, there are sm, md, lg, xl and full. You can change the size via prop size. Default size are md.

preview
vue
<template>
  <p-modal
    v-model="modalSize"
    title="Modal Title"
    size="sm">
    <div>
      <blockquote>
        A wonderful serenity has taken possession of my entire soul,
        like these sweet mornings of spring which I enjoy with my whole heart.
      </blockquote>
    </div>
    <template #footer="{ close }">
      <p-button @click="close" color="info">
        Button Text
      </p-button>
    </template>
  </p-modal>
</template>

Modal fullscreen is configured by prop size with full value. There are two type of modal fullscreen, default and free-distraction.

Default Fullscreen

preview
vue
<template>
  <p-modal
    v-model="modal"
    title="Modal Title"
    text="This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information."
    size="full"
    header-class="px-6"
    body-class="p-6">
  </p-modal>
</template>
preview
vue
<script setup>
  import IconDocument from '@privyid/persona-icon/vue/document-empty/20.vue'
</script>

<template>
  <p-modal
    v-model="modal"
    text="This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information."
    size="full"
    header-class="px-6"
    body-class="p-6">
    <template #header>
      <div class="space-x-3 modal__title">
        <IconDocument />
        <p-text class="text-subtle">Letter of agreement</p-text>
        <p-label color="warning" variant="dot">Waiting</p-label>
      </div>
    </template>
  </p-modal>
</template>
preview
vue
<script setup>
  import IconNext from '@privyid/persona-icon/vue/chevron-right/20.vue'
  import IconPrev from '@privyid/persona-icon/vue/chevron-left/20.vue'
  import IconDocument from '@privyid/persona-icon/vue/document-empty/20.vue'
  import IconClose from '@privyid/persona-icon/vue/close/20.vue'
</script>

<template>
  <p-modal
    v-model="modal"
    body-class="grid h-full grid-cols-8"
    size="full">
    <template #header>
      <div class="overflow-y-auto modal--full__header__content bg-default-alpha dark:bg-dark-default-alpha">
        <div class="flex items-center p-3 space-x-3 bg-default dark:bg-dark-default">
          <IconDocument />
          <p-text>Letter of Agreement..</p-text>
          <IconClose class="cursor-pointer text-muted dark:text-dark-muted hover:text-subtle dark:hover:text-dark-subtle" />
        </div>
      </div>
      <div class="modal--full__header__navigation">
        <p-button icon variant="ghost"><IconPrev /></p-button>
        <p-button icon variant="ghost"><IconNext /></p-button>
      </div>
    </template>
    <template #body>
        <div class="col-span-2 bg-default dark:bg-dark-default p-7">
          <p-subheading weight="bold">Document properties</p-subheading>
        </div>
        <div class="col-span-4 px-4 pt-4 bg-subtlest dark:bg-dark-subtlest">
          <div class="h-full p-6 rounded-t-lg shadow-sm bg-default dark:bg-dark-default">
            This is place holder text. The basic dialog for modals
            should contain only valuable and relevant information.
          </div>
        </div>
        <div class="col-span-2 p-7 bg-default dark:bg-dark-default">
          <p-subheading weight="bold">Set e-Meterai</p-subheading>
        </div>
    </template>
  </p-modal>
</template>

Free Distraction

Activate modal free distraction type is by adding free-distraction prop in the modal size full. Slot body cannot be used in this modal type.

preview
vue
<template>
  <p-modal
    v-model="modal"
    title="Modal Title"
    text="This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information."
    size="full"
    free-distraction>
  </p-modal>
</template>

Centered Modal

Modal can be vertically center in the viewport by setting centered prop.

preview
vue
<template>
  <p-modal
    v-model="modalCenter"
    title="Modal Title"
    size="sm"
    centered>
    <div>
      This is place holder text. The basic dialog for modals
      should contain only valuable and relevant information.
    </div>
    <template #footer="{ close }">
      <p-button @click="close" color="info">
        Button Text
      </p-button>
    </template>
  </p-modal>
</template>

Variables

Modal use local CSS variables on .modal for enhanced real-time customization.

sass
--p-modal-size-xl: 960px;
--p-modal-size-lg: 800px;
--p-modal-size-md: 600px;
--p-modal-size-sm: 400px;
--p-modal-z-index: theme(zIndex.modal);
--p-modal-body-scrollable-max-height: theme(spacing.64);
--p-modal-body-scrollable-min-height: 0;
--p-modal-content-margin-y: theme(spacing.8);

API

Props

PropsTypeDefaultDescription
modelValueBooleanfalsev-model value for show / hide modal
titleString-Modal Title
textString-Text inside of Modal Body
dismissableBooleantrueShow / Hide dismiss button
sizeStringmdSize of modal, valid value is sm, md, lg and xl
bannerBooleanfalseGive modal no-padding to place image for specific purpose
noCloseOnEscBooleanfalseNo close modal while Escape was pressed
noCloseOnBackdropBooleanfalseNo close modal while Modal Backdrop was clicked
modalBodyScrollableBooleanfalseScrollable modal body when content is to long
centeredBooleanfalseHandle center vertically of the viewport
freeDistractionBooleanfalseActivate modal free distraction type when size are full
headerClassString or Array or Object-CSS class to add in the modal header
dialogClassString or Array or Object-CSS class to add in the modal dialog
contentClassString or Array or Object-CSS class to add in the modal content
bodyClassString or Array or Object-CSS class to add in the modal body
footerClassString or Array or Object-CSS class to add in the modal footer

Slots

NameDescription
header Content (in the form of— permalink or button) to place in Modal Header
body Content to place in Modal body of size full with default type only
footer Content (in the form of— permalink or button) to place in Modal Footer. Modal size full with default type not supported this slot.

Events

NameArgumentsDescription
close-Event when close button clicked
hide-Event when modal hidden
show-Event when modal shown

Released under the MIT License.