useModal
Open a modal programmatically from anywhere.
useModal() lets you open a <SModal> (or any component you point it at)
without placing it in your template - useful for confirmation dialogs
triggered from a click handler, or flows where the modal's content isn't
known until runtime.
Usage
<script setup lang="ts">
const { open } = useModal()
const modal = useTemplateRef('confirmModal')
async function handleDelete() {
const confirmed = await open(ConfirmDeleteDialog, {
props: { itemName: 'My project' },
})
if (confirmed) {
// ...
}
}
</script>
The component you pass to open() resolves the returned promise by emitting
close with its result. Escape, an outside click, or the shell's close button
resolve it with undefined.
API
function useModal(): {
open: <T = void>(component: Component, options?: UseModalOpenOptions) => Promise<T | undefined>
}
open() resolves with undefined if the modal is dismissed without an
explicit value (e.g. Escape, backdrop click).
UseModalOpenOptions
| Option | Type | Description |
|---|---|---|
props | Record<string, unknown> | Props passed to the opened component. |
title | string | Registered with Reka as the dialog's accessible name, visually hidden - the opened component still supplies its own visible header via the content slot. |
description | string | Registered with Reka as the dialog's accessible description, visually hidden. |
dismissible | boolean | Whether Escape/backdrop click closes it. |
modal | boolean | Whether it traps focus and blocks interaction outside. |
overlay | boolean | Whether a backdrop is rendered. |
transition | boolean | Whether the open/close animation plays. |
Every option is forwarded straight through to the underlying SModal
instance, and defaults to SModal's own defaults when omitted. Since the
opened component always renders through SModal's content slot (see
Modal), title/description
are the only way to give a programmatically-opened dialog a real
accessible name/description - pass them if the opened component's own
content doesn't already include a heading Reka can associate with it.
Setup
The render loop that actually mounts opened modals lives inside <SApp> -
wrap your app's root with it once (typically in app.vue) and useModal()
works anywhere underneath:
<SApp>
<NuxtPage />
</SApp>