0.3.0 • Published 3 years ago

vue-material-modal-dialog v0.3.0

Weekly downloads
24
License
MIT
Repository
github
Last release
3 years ago

A reusable modal dialog for Vue Material

Minified size Open issues Vulnerabilities Total downloads License

In Vue Material, components showing a dialog have to contain an MdDialog, or a component based on MdDialog. This couples the modal dialog to the surrounding component and creates a separate dialog instance/comment placeholder for each occurrence, eventually multiplied by v-for.

This repository provides a component, MdModalDialog, that avoids this situation. It acts as a substitute for Vue Material's MdDialog, offering the following additional features:

  • MdModalDialogs are completely decoupled from other components
  • They only have to be imported but not to be placed in the <template> of other components
  • MdModalDialog supports the same props and events as MdDialog
  • You can show MdModalDialogs from anywhere in your app (e.g. from a Vuex action), not only from component methods
  • Simple API: showing the dialog returns a promise which will be fulfilled or rejected when the dialog is closed
  • Input data can be transferred from the dialog to the calling component
  • Properties can be passed for runtime customization of the dialog
  • At any point in time there will be at most one single MdModalDialog instance

A simple online example is available here (example source code).

Installation

As a module:

$ npm install vue-material-modal-dialog
    or
$ yarn add vue-material-modal-dialog

Included as <script>:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-material-modal-dialog/dist/components.css">
<script src="https://cdn.jsdelivr.net/npm/vue-material-modal-dialog/dist/components.min.js"></script>

Usage

Registering the MdModalDialog component

import MdModalDialog from 'vue-material-modal-dialog'
import 'vue-material-modal-dialog/dist/md-modal-dialog.css'
    ...
// This must come after Vue.use(VueMaterial):
Vue.use(MdModalDialog)

Controlling modal dialogs

MdModalDialog provides these functions:

vm.$modal.show(dialog, [props]), Vue.$modal.show(dialog, [props])

  • {Vue component} dialog
  • {Object} [props]

Shows a dialog component in pristine state, can pass props to the dialog instance; does not preserve the dialog state across show() calls.

Returns a Promise that can be fulfilled by vm.$modal.submit() and rejected by vm.$modal.cancel(). Either function closes the dialog.

vm.$modal.submit([result]), Vue.$modal.submit([result])

  • {Any} [result]

Closes the dialog and fulfills the Promise; can return a result.

vm.$modal.cancel([reason]), Vue.$modal.cancel([reason])

  • {Any} [reason]

Closes the dialog and rejects the Promise; can return a reason for rejection.

Creating modal dialog components

Just use MdModalDialog in the same way as you would use MdDialog (without md-active), for example for an input dialog:

<template>
  <md-modal-dialog>
    <md-dialog-title>Guess a number</md-dialog-title>

    <md-dialog-content>
      <md-field>
        <label>A number</label>
        <md-input type="number" v-model="number" />
      </md-field>
    </md-dialog-content>

    <md-dialog-actions>
      <md-button @click="$modal.submit(number)">Submit</md-button>
      <md-button @click="$modal.cancel()">Cancel</md-button>  
    </md-dialog-actions>
  </md-modal-dialog>
</template>

<script>
  export default {
    name: 'GuessDialog',
      ...
  }
</script>

Showing GuessDialog and receiving the guessed number in some other component:

vm.$modal
    .show(GuessDialog)
    .then(number => {
        // Do something with "number"
    })
    .catch(reason => {
        // In order to avoid runtime warnings, a catch clause
        // is required even if "reason" is ignored
    })      
} 

Passing properties to modal dialogs

Since MdModalDialogs are not placed like regular components, no props can be passed to them. However, using v-slot, we can pass properties to such a dialog every time it is shown.

Let us extend the example with a configurable upper limit max for the guessed number:

<template>
  <md-modal-dialog v-slot="{ max }">
    <md-dialog-title>Guess a number up to {{ max }}</md-dialog-title>

    <md-dialog-content>
      <md-field>
        <label>A number</label>
        <md-input type="number" v-model="number" :max="max" />
      </md-field>
    </md-dialog-content>
    ...
</template>
...

Showing GuessDialog and passing a max value:

vm.$modal
    .show(GuessDialog, { max: 42 })
    .then(...)
    .catch(...)

In the methods of the modal dialog component, such properties can be accessed through the object vm.$modal.slotProps.

Returning a reason on ESC and outside clicks

  • If a dialog is configured to be closed by clicking outside and/or by ESC,
  • and if a reason is to be returned in these cases

then this is one possible approach:

<template>
  <md-modal-dialog
    @md-clicked-outside="$modal.cancel('byClick')"
    @keydown.esc="$modal.cancel('byEsc')">
      ...
    <md-button @click="$modal.cancel('byButton')">Cancel</md-button>
      ...
  </md-modal-dialog>
</template>

License

Software: MIT

Documentation: CC-BY-SA 4.0

0.3.0

3 years ago

0.2.3

4 years ago

0.2.2

4 years ago

0.2.1

4 years ago

0.2.0

4 years ago

0.1.8

4 years ago

0.1.7

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.4

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago