Universal Accessible Modal Component For Vue 3

A feature-rich, accessible, and customizable modal plugin for Vue 3 applications.

How to use it:

1. Import the modal component.

import 'vue-universal-modal/dist/index.css'
import VueUniversalModal from 'vue-universal-modal'
app.use(VueUniversalModal, {
  teleportTarget: '#modals'
})

2. Create a basic modal window.

<template>
  <div>
    <button
      :class="style.button"
      @click="showModal"
    >
      Show modal
    </button>
  </div>
  <Modal
    :model-value="true"
    :close="closeModal"
    :disabled="!isShow"
  >
    <div class="modal">
      <p>
        change v-show
      </p>
      <button
        :class="style.button"
        @click="closeModal"
      >
        close
      </button>
    </div>
  </Modal>
</template>
import { defineComponent, ref } from 'vue'
import { style } from './style'
export default defineComponent({
  setup () {
    const isShow = ref(false)
    function showModal () {
      isShow.value = true
    }
    function closeModal () {
      isShow.value = false
    }
    return {
      isShow,
      showModal,
      closeModal,
      style
    }
  }
})

3. With options and modal-in-modal.

<template>
  <div>
    <button
      :class="style.button"
      @click="showModal('modal1')"
    >
      Show modal
    </button>
  </div>
  <Modal
    v-model="isShowModal.modal1"
    :close="() => closeModal('modal1')"
    :options="options"
    :style="{ backgroundColor: 'rgba(59, 130, 246, 0.3)' }"
  >
    <div class="modal">
      <p>
        modal1
      </p>
      <button
        :class="style.button"
        class="mr-2"
        @click="showModal('modal2')"
      >
        open modal2
      </button>
      <button
        :class="style.button"
        @click="() => closeModal('modal1')"
      >
        close
      </button>
    </div>
  </Modal>
  <Modal
    v-model="isShowModal.modal2"
    :close="() => closeModal('modal2')"
    :options="options"
  >
    <div class="modal">
      <p>
        modal2
      </p>
      <button
        :class="style.button"
        @click="() => closeModal('modal2')"
      >
        close
      </button>
    </div>
  </Modal>
</template>
import { defineComponent, reactive } from 'vue'
import { style } from './style'
export default defineComponent({
  setup () {
    const isShowModal = reactive({
      modal1: false,
      modal2: false
    })
    const options = {
      transition: false,
      closeClickDimmed: false,
      closeKeyCode: false,
      styleModalContent: { justifyContent: 'flex-start' }
    }
    function showModal (key: 'modal1' | 'modal2') {
      isShowModal[key] = true
    }
    function closeModal (key: 'modal1' | 'modal2') {
      isShowModal[key] = false
    }
    return {
      isShowModal,
      options,
      showModal,
      closeModal,
      style
    }
  }
})

4. Customize the animation.

.vue-universal-modal-enter-from,
.vue-universal-modal-enter-to,
.vue-universal-modal-leave-from,
.vue-universal-modal-leave-to {
  .modal {
    transition: 0.3s transform;
  }
}
.vue-universal-modal-enter-to .modal,
.vue-universal-modal-leave-from .modal {
  transform: translate3d(0, 0, 0);
}
.vue-universal-modal-enter-from .modal,
.vue-universal-modal-leave-to .modal {
  transform: translate3d(0, 50px, 0);
}

5. Events.

<template>
  <div>
    <button
      :class="style.button"
      @click="showModal"
    >
      Show modal
    </button>
  </div>
  <Modal
    v-model="isShow"
    :close="closeModal"
    @before-enter="beforeEnter"
    @after-enter="afterEnter"
    @before-leave="beforeLeave"
    @after-leave="afterLeave"
  >
    <div class="modal">
      <p>
        Hello
      </p>
      <button
        :class="style.button"
        @click="closeModal"
      >
        close
      </button>
    </div>
  </Modal>
</template>
import { defineComponent, ref } from 'vue'
import { style } from './style'
export default defineComponent({
  setup () {
    const isShow = ref(false)
    function showModal () {
      isShow.value = true
    }
    function closeModal () {
      isShow.value = false
    }
    function beforeEnter () {
      console.log('before enter')
    }
    function afterEnter () {
      console.log('after enter')
    }
    function beforeLeave () {
      console.log('before leave')
    }
    function afterLeave () {
      console.log('after leave')
    }
    return {
      isShow,
      showModal,
      closeModal,
      style,
      beforeEnter,
      afterEnter,
      beforeLeave,
      afterLeave
    }
  }
})

Preview:

Universal Accessible Modal Component For Vue 3

Changelog:

v1.1.4 (06/25/2022)

  • update dependencies

v1.1.3 (08/10/2021)

  • Change background mouse click event to mousedown, mouseup

Download Details:

Author: hoiheart

Live Demo: https://hoiheart.github.io/vue-universal-modal/demo/index.html

Download Link: https://github.com/hoiheart/vue-universal-modal/archive/refs/heads/master.zip

Official Website: https://github.com/hoiheart/vue-universal-modal

Install & Download:

# NPM
$ npm i vue-universal-modal --save

Add Comment