Dialog
A Dialog component is a modal window that can be used to display information or ask for user input. It is a wrapper around the Headless UI Dialog component.
Preview & Playground 🖼️
Here you may find a preview of the component, with error & possible variants.
🏄 Click to expand the code
<script setup lang="ts">
import { Button, Dialog, RichSelect } from '@flavorly/vanilla-components'
import { ref } from 'vue'
import CheckIcon from '~icons/heroicons/check-solid'
const open = ref(false)
const open2 = ref(false)
const valueFromSelect = ref()
const shouldDivide = ref(false)
const position = ref('center')
const openDivided = () => {
open2.value = !open2.value
shouldDivide.value = true
}
const openPlain = () => {
open2.value = !open2.value
shouldDivide.value = false
}
const openAligned = (align = 'center') => {
open2.value = !open2.value
position.value = align
shouldDivide.value = false
}
</script>
<template>
<PreviewWrapper>
<div class="flex flex-col items-center justify-center mx-auto space-y-3 ">
<Button
label="Open Dialog"
@click="open = !open"
/>
<Button
label="Open another Dialog"
@click="openPlain"
/>
<Button
label="Open Divided Dialog"
@click="openDivided"
/>
<Button
label="Centered Dialog"
@click="openAligned('center')"
/>
<Button
label="Bottom Dialog"
@click="openAligned('bottom')"
/>
<Button
label="Top Dialog"
@click="openAligned('top')"
/>
</div>
<Dialog v-model="open">
<div>
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
<CheckIcon
class="h-6 w-6 text-green-600"
aria-hidden="true"
/>
</div>
<div class="mt-3 text-center sm:mt-5">
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-white">
🎉 Thank you for testing Vanilla!
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500 dark:text-gray-400">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
</p>
</div>
<div class="my-2">
<RichSelect
v-model="valueFromSelect"
:options="[
{ value: 'Option 1', text: 'One Option' },
{ value: 'Option 2', text: 'Two Options' },
]"
:teleport="true"
:clearable="true"
:hide-search-box="true"
feedback="Im useful helper out here, choose wisely"
placeholder="Please select an option"
/>
</div>
</div>
</div>
<div class="mt-5 sm:mt-6">
<Button
type="button"
class="w-full"
variant="primary"
@click="open = false"
>
Yeah, now close me.
</Button>
</div>
</Dialog>
<Dialog
v-model="open2"
:divided="shouldDivide"
:position="position"
title="Another Dialog"
>
<div class="text-center">
<p class="text-sm text-gray-500 dark:text-gray-200">
This is just another modal, divided, and with padded body
and also two action buttons.
</p>
</div>
<template #footer>
<Button
type="button"
variant="primary"
@click="open2 = false"
>
Yeah, now close me.
</Button>
<Button
type="button"
variant="secondary"
@click="open2 = false"
>
No wait.
</Button>
</template>
</Dialog>
</PreviewWrapper>
</template>
Props 📥
Props available for this component extending the default variant & global props.
Prop | Description | Accepted Values | Default |
---|---|---|---|
modelValue | Controls the open/close of the dialog | Boolean | false |
title | A title for the dialog | String | undefined |
teleport | If we should teleport the dropdown | Boolean | true |
teleportTo | Element to teleport | string | body |
closeableOnClickOutside | Clicking outside closes the dialog | Boolean | true |
overlay | Adds a overlay behind the dialog | Boolean | true |
closeable | If we should allow open/close the dialog | Boolean | true |
closeableOnPressEscape | Keyboard ESC closes the dialog | Boolean | true |
padding | Give padding to the whole modal | Boolean | false |
paddingBody | Give padding to the Body of the modal | Boolean | true |
divided | Divide header and footer with border | Boolean | false |
divided | Divide header, body & footer | Boolean | true |
as | Render the modal as this element | String | div |
size | Size of the modal | default ,small ,medium ,large ,full | default |
position | Position of the modal | center-bottom , center-top , center , top , bottom | center |
Slots 🧬
Current slots available for this component are the following:
Slot default
Actual content to show inside the modal
Slot header
Header part of the modal, usually used to place the title or/and subtitle.
Slot footer
Footer part of the modal, usually used to place buttons or actions.
Events 🚇
Here you may find the events emitted by this component.
Event | Description | Value |
---|---|---|
update:modelValue | When the value changes | any |
| open
| Dialog was opened | Boolean
| | close
| Dialog was closed | Boolean
| | opening
| Dialog is about to be opened — before the transition starts | Boolean
| | opened
| Dialog was opened — after the transition finishes | Boolean
| | closing
| Dialog is about to be closed — before the transition starts | Boolean
| | closed
| Dialog was closed — after the transition finishes | Boolean
|
💡 A note on closing and open
The open
and close
events are emitted when the dialog is opened or closed, but the modelValue
is not updated yet. It will take a few milliseconds in order to circumvent the transition
effect and provide a smooth experience.
Additional Components
Because this is mostly a wrapper around HeadlessUI, you can still use the native headlessUI compoments like DialogTitle
to achieve any accessibility needs.
Footer
The dialog footer component is a smart component that will take from 1 to 3 items and will divide them in a smart way. This is really useful when you have one or more actions on the dialog, it will make sure to apply the correct grid.