Guide
Writing a modal
Structure of a modal component using ModalRoot, ModalContent, and useModalContext.
Writing a modal
A modal is a regular Vue SFC. Wrap your markup in <ModalRoot> + <ModalContent>, then use useModalContext<T>() to resolve or reject the promise returned by openModal.
Required structure
<ModalRoot> ← dialog root; manages presence, ARIA, events
<ModalContent> ← visible card; drives data-state animations
<ModalTitle> ← labels the dialog
<ModalDescription> ← describes the dialog
…content…
</ModalContent>
</ModalRoot>
<ModalRoot> must contain a <ModalContent>. The exit-animation wait lives inside <ModalContent> — without it, the modal hangs in the DOM forever.
Complete example
ConfirmDialog.vue
<script setup lang="ts">
import {
ModalContent,
ModalDescription,
ModalRoot,
ModalTitle,
useModalContext
} from '@kolirt/vue-modal'
defineOptions({ modalGroup: 'default' })
const props = defineProps<{
title: string
message: string
}>()
const { close, confirm } = useModalContext<boolean>()
</script>
<template>
<ModalRoot class="root">
<ModalContent class="card">
<ModalTitle>{{ props.title }}</ModalTitle>
<ModalDescription>{{ props.message }}</ModalDescription>
<div class="actions">
<button @click="close()">Cancel</button>
<button @click="confirm(true)">OK</button>
</div>
</ModalContent>
</ModalRoot>
</template>
<style scoped>
.root {
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
}
.card {
width: 100%;
max-width: 24rem;
padding: 1.5rem;
border-radius: 0.5rem;
background: white;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1.5rem;
}
</style>
Open it from anywhere:
import { openModal } from '@kolirt/vue-modal'
import ConfirmDialog from './ConfirmDialog.vue'
const ok = await openModal<boolean>(ConfirmDialog, {
props: { title: 'Delete?', message: 'This cannot be undone.' }
}).catch(() => false)
Because modalGroup: 'default' is declared on the component, group doesn't need to be passed at the call site.
What useModalContext gives you
const {
id, // number — unique id of this modal instance
group, // ModalGroup — the group this modal belongs to
isClosing, // ComputedRef<boolean> — exit animation in progress
isTopmost, // ComputedRef<boolean> — topmost within its group
isTopmostGlobal, // ComputedRef<boolean> — topmost across all groups
effectiveOptions, // ComputedRef<ModalEffectiveOptions> — merged behavior
close, // (opts?) => void — reject the promise
confirm, // (data, opts?) => void — resolve the promise
onBeforeClose // (handler) => void — register a close guard
} = useModalContext<boolean>()
useModalContext() throws if called outside a modal component. See the Modal context page for a full reference.
