Dialog

Demos

Sizes and fullscreen

Available size/dimension variants for the ui prop: s / m / narrow / medium / wide / auto.

s / m are used to specify size for internal content and will be inherited by components inside the dialog. While narrow / medium / wide / fullscreen / auto are used to specify the dimension of the dialog itself, thus can be used together with s / m.

Edit this page on GitHubEdit
<template>
<article>
  <veui-button @click="openDialog('s')">
    s
  </veui-button>
  <veui-button @click="openDialog('m')">
    m
  </veui-button>
  <veui-button @click="openDialog('narrow')">
    narrow
  </veui-button>
  <veui-button @click="openDialog('medium')">
    medium
  </veui-button>
  <veui-button @click="openDialog('wide')">
    wide
  </veui-button>
  <veui-button @click="openDialog('fullscreen')">
    fullscreen
  </veui-button>
  <veui-button @click="openDialog('auto')">
    auto
  </veui-button>
  <veui-dialog
    title="System"
    :ui="ui"
    :open.sync="open"
  >
    <section>Current UI: "{{ ui }}"</section>
    <section v-if="ui === 's' || ui === 'm'">
      <veui-button>Button size: {{ ui }}</veui-button>
      <veui-switch>{{ ui }}</veui-switch>
    </section>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, Switch } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button,
    'veui-switch': Switch
  },
  data () {
    return {
      open: false,
      ui: null
    }
  },
  methods: {
    openDialog (size) {
      this.ui = size
      this.open = true
    }
  }
}
</script>

<style lang="less" scoped>
.veui-button {
  margin-right: 20px;
}
</style>
Edit this page on GitHubEdit
<template>
<article>
  <veui-button @click="modalOpen = true">
    Modal
  </veui-button>
  <veui-button @click="nonModalOpen = true">
    Non-modal
  </veui-button>
  <veui-dialog
    title="System"
    :open.sync="modalOpen"
    @ok="handleModalClose(true)"
    @cancel="handleModalClose"
  >
    Do you want to refresh the page?
  </veui-dialog>
  <veui-dialog
    title="System"
    :open.sync="nonModalOpen"
    :modal="false"
    @ok="handleModalClose(true)"
    @cancel="handleModalClose"
  >
    Do you want to refresh the page?
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      modalOpen: false,
      nonModalOpen: false
    }
  },
  methods: {
    handleModalClose (ok) {
      this.modalOpen = false
      if (ok) {
        location.reload()
      }
    },
    handleNonModalClose (ok) {
      this.nonModalOpen = false
      if (ok) {
        location.reload()
      }
    }
  }
}
</script>

<style lang="less" scoped>
.veui-button {
  margin-right: 20px;
}
</style>

Customized content

Edit this page on GitHubEdit
<template>
<article>
  <veui-button @click="simpleOpen = true">
    Title & content
  </veui-button>
  <veui-dialog
    :open.sync="simpleOpen"
    title="Customized Title & Content"
    @ok="simpleOpen = false"
    @cancel="simpleOpen = false"
  >
    Customized content via <code>&lt;slot&gt;</code>.
  </veui-dialog>

  <veui-button @click="titleIconOpen = true">
    Icon in Title
  </veui-button>
  <veui-dialog
    :open.sync="titleIconOpen"
    @ok="titleIconOpen = false"
    @cancel="titleIconOpen = false"
  >
    <template #title>
      Title with Icon <veui-icon name="flag"/>
    </template>
    Customized content via <code>&lt;slot&gt;</code>.
  </veui-dialog>

  <veui-button @click="footOpen = true">
    Foot
  </veui-button>
  <veui-dialog
    :open.sync="footOpen"
    title="Customized Foot"
  >
    Customized content via <code>&lt;slot&gt;</code>.
    <template #foot="{ close }">
      <veui-button
        ui="s primary"
        @click="close('ok')"
      >
        Close
      </veui-button>
    </template>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, Icon } from 'veui'
import 'veui-theme-dls-icons/flag'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button,
    'veui-icon': Icon
  },
  data () {
    return {
      simpleOpen: false,
      titleIconOpen: false,
      footOpen: false
    }
  }
}
</script>

<style lang="less" scoped>
.veui-button {
  margin-right: 20px;
}
</style>

Async support

When you want a unified process to handle all user interactions that might trigger the dialog to be closed, you can leverage the before-close function prop. No matter the close behavior is about to be triggered by clicking “OK”/“Cancel” buttons, the close button or pressing esc, before-close will always take over the following process. If the logic is relatively simple, you can manipulate open prop directly to close the dialog.

Edit this page on GitHubEdit
<template>
<article>
  <veui-button
    :disabled="submitting"
    @click="submitOpen = true"
  >
    Submit
  </veui-button>
  <veui-button
    :disabled="saving"
    @click="saveOpen = true"
  >
    Save
  </veui-button>
  <veui-dialog
    title="System"
    :open.sync="submitOpen"
    :before-close="submit"
    :closable="false"
    :escapable="!submitting"
    :loading="submitting"
  >
    Confirm to create the issue?
  </veui-dialog>
  <veui-dialog
    title="System"
    :open.sync="saveOpen"
    :closable="false"
    :escapable="!submitting"
  >
    Confirm to save the post?
    <template #foot>
      <veui-button
        ui="primary"
        :loading="saving"
        @click="save('ok')"
      >
        OK
      </veui-button>
      <veui-button
        :disabled="saving"
        @click="save"
      >
        Cancel
      </veui-button>
    </template>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, toast } from 'veui'

function fakeRequest () {
  return new Promise(resolve =>
    setTimeout(() => {
      resolve(Math.random() < 0.5)
    }, 2000)
  )
}

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      submitOpen: false,
      saveOpen: false,
      submitting: false,
      saving: false
    }
  },
  methods: {
    submit (type) {
      if (type === 'ok') {
        this.submitting = true
        return fakeRequest().then(success => {
          this.submitting = false
          if (!success) {
            toast.error('Failed to create the issue. Please retry.')
            return false
          }
          toast.success('Issue created successfully!')
        })
      }
    },
    save (type) {
      if (type === 'ok') {
        this.saving = true
        return fakeRequest().then(success => {
          this.saving = false
          if (!success) {
            toast.error('Failed to save the post. Please retry.')
          } else {
            toast.success('Post saved successfully!')
            this.saveOpen = false
          }
        })
      }
      this.saveOpen = false
    }
  }
}
</script>

<style lang="less" scoped>
article > .veui-button {
  margin-right: 20px;
}
</style>

Draggable

Edit this page on GitHubEdit
<template>
<article>
  <veui-button @click="draggableOpen = true">
    Draggable
  </veui-button>
  <veui-dialog
    :open.sync="draggableOpen"
    title="Draggable Dialog"
    draggable
    @ok="draggableOpen = false"
    @cancel="draggableOpen = false"
  >
    This dialog is draggable.
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      draggableOpen: false
    }
  }
}
</script>

<style lang="less" scoped>
.veui-button {
  margin-right: 20px;
}
</style>

Stacking order

Open both dialogs and drag one of them to make them overlap a little bit. Then when you activate one dialog, it will be displayed on top of the other one.

Edit this page on GitHubEdit
<template>
<article>
  <veui-button @click="aOpen = true">
    Dialog A
  </veui-button>
  <veui-dialog
    :open.sync="aOpen"
    title="Dialog A"
    draggable
    :modal="false"
    @ok="aOpen = false"
    @cancel="aOpen = false"
  >
    The content of Dialog A.
  </veui-dialog>

  <veui-button @click="bOpen = true">
    Dialog B
  </veui-button>
  <veui-dialog
    :open.sync="bOpen"
    title="Dialog B"
    draggable
    :modal="false"
    @ok="bOpen = false"
    @cancel="bOpen = false"
  >
    The content of Dialog B.
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      aOpen: false,
      bOpen: false
    }
  }
}
</script>

<style lang="less" scoped>
.veui-button {
  margin-right: 20px;
}
</style>

API

Props

NameTypeDefaultDescription
uistring=-

Style variants.

ValueDescription
sSmall sized content (not the dimension of the dialog itself).
mMedium sized content (not the dimension of the dialog itself).
narrowNarrow width.
mediumMedium width.
wideWide width.
fullscreenFullscreen dialogs.
autoAuto-fit dialogs.
modalboolean=trueWhether to display a backdrop to block interactions with the content underneath. Modal dialogs preempt focus by default (will return focus when closed).
titlestring=-The title of the dialog. Will be ignored if title slot is specified.
openboolean=false

.sync

Whether the dialog is open.

closableboolean=trueWhether to display a close button at the top right corner.
outside-closableboolean=falseWether to close the dialog when user click outside.
draggableboolean=falseWhether the dialog is draggable.
escapableboolean=falseWhether to allow closing the dialog after pressing esc. Only works when closable is set to true.
inlineboolean=falseWhether the dialog is displayed inline thus takes up space.
footlessboolean=falseWhether to hide the default footer.
loadingboolean=falseWehter the dialog is in loading state. When loading, the OK button will enter loading state as well and become unclickable.
disabledboolean=falseWehter the dialog is disabled. When disabled, the OK button will be disabled as well and become unclickable.
ok-labelstring=-The text content of the “OK” button.
cancel-labelstring=-The text content of the “Cancel” button.
prioritynumber=-The stacking priority of the dialog overlay. See the priority prop of Overlay component.
before-closefunction(string): boolean=|Promise<boolean=>-

Executed when user interaction is about to trigger closing the dialog. The type is function(type: string): boolean=|Promise<boolean=>, where type being the action type of the closing behavior. Available values by default are 'ok'/'cancel'. The return value can be a boolean or a Promise that resolves a boolean value, to handle the situation that an async process is responsible for deciding whether to close the dialog. Will keep the dialog open when returning false or the Promise resolves with false.

<veui-dialog :open.sync="dialogOpen" :before-close="submit">...</veui-dialog>
methods: {
  submit (type) {
    if (type === 'ok') {
      return axios.post('/item/create', {/* ... */})
        .then(({ id, error }) => {
          if (error) {
            this.showError(error)
            return false // resolving `false` will keep the dialog open
          }
        })
    }
    // resolving non-`false` value will close the dialog
  },
  // ...
}
overlay-classstring | Object=-The class expression applied to the root element of the dialog overlay. See the overlay-class prop of Overlay component.
overlay-stylestring | Array | Object=-See the overlay-style prop of the Overlay component.

Slots

NameDescription
defaultThe content of the dialog.
titleThe title of the dialog. Will ignore the title prop if this slot is specified.
foot

The foot of the dialog. Displays “OK” and “Cancel” buttons by default.

NameTypeDescription
closefunction(type: string): voidThe callback to trigger closing the dialog. type is the action type and will be passed into before-close hook as the first argument. And an event named after type will be triggered synchronously.

Events

NameDescription
okTriggered after the “OK” button is clicked or the dialog is closed with the slot scope function call close('ok').
cancelTriggered after the “Cancel” button or the close button is clicked, or esc is pressed, or the dialog is closed with the slot scope function call close('cancel').
<value>Triggered when the dialog is closed with the slot scope function call close(value).
aftercloseTriggered after the dialog is closed. If leave transition is provided by theme, then afterclose will be triggered when the transition finishes.

Icons

NameDescription
closeClose.
Edit this page on GitHubEdit