AndrewBastin / vue-promise-modals

A Vue 3 library to create modals that are resolved with promises.
https://vue-promise-modals.andrewbast.in
MIT License
4 stars 1 forks source link
dialog modals promise vue
# vue-promise-modals

A Vue 3 library to create modals that are resolved with promises.

A demo of this library is available at vue-promise-modals.andrewbast.in.

Installation

Usage

vue-promise-modals exposes a useModals composable that returns the openModal function that can be used to open modals. The modals are 'resolved' using either the modal-resolve (for successful completion) or modal-reject (for failure) events.

Example Modal Component

<!-- GreetModal.vue -->
<template>
  <dialog open>
    <h1>Hello {{ props.name }}!</h1>

    <button @click="emit('modal-reject')">
      Close
    </button>
  </dialog>
</template>

<script setup lang="ts">
// Use props to define modal inputs
const props = defineProps<{
  name: string
}>();

// Use emits to define modal outputs
const emit = defineEmits<{
  (e: 'modal-reject'): void // Emit can also accept a payload
  (e: 'modal-resolve', value: { name: string }): void
}>();
</script>

Summoning the modal

<script setup lang="ts">
import { useModals } from 'vue-promise-modals';
import GreetModal from "./GreetModal.vue";

const { openModal } = useModals()

async function openDialog() {
  try {
    const result = await openModal(GreetModal, {
      // Props go here (and its type checked!)
      name: `Modal ${counter++}`,
    })

    // The result value will be the same value emitted through the `modal-resolve` event
    console.log(result.name)
  } catch (e) {
    // The error value will be the same value as emitted through the `modal-reject` event
    console.log("Modal Rejected:", e)
  }
}
</script>

Transitions

Transition animations can be applied to the modals by passing in the options in the vue-promise-modals Vue plugin. The plugin options follow the same options as the props accepted by the Vue TransitionGroup element.

import { createApp } from 'vue'
import App from './App.vue'
import { plugin } from "vue-promise-modals"

createApp(App)
.use(plugin, {
  transition: {
    name: "modal" // Uses the modal-* classes for transition animations for the modals
  }
})
.mount('#app')