@anfo/nuxt-dialogs-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +162 -0
- package/SKILL.md +274 -0
- package/dist/module.cjs +283 -0
- package/dist/module.cjs.map +1 -0
- package/dist/module.d.cts +23 -0
- package/dist/module.d.ts +23 -0
- package/dist/module.js +267 -0
- package/dist/module.js.map +1 -0
- package/dist/runtime.cjs +74 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +37 -0
- package/dist/runtime.d.ts +37 -0
- package/dist/runtime.js +43 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# @anfo/nuxt-dialogs-plugin
|
|
2
|
+
|
|
3
|
+
A Nuxt module that auto-scans a directory for Vue dialog/drawer components and exposes them through a fully type-safe virtual module (`virtual:dialogs`). Dialogs are mounted programmatically into isolated Vue app instances — no `<Teleport>` boilerplate, no global store, automatic cleanup on close.
|
|
4
|
+
|
|
5
|
+
**Nuxt-native extras** — dialog apps automatically inherit the Nuxt app's context, so Pinia, i18n, UI libraries, global components and directives work inside dialogs with zero wiring. `dialogs` and the runtime composables are auto-imported.
|
|
6
|
+
|
|
7
|
+
> This is the Nuxt counterpart of [`@anfo/vite-dialogs-plugin`](https://github.com/) — it is a standalone package and does not depend on it.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -D @anfo/nuxt-dialogs-plugin
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Register the module — `nuxt.config.ts`
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
export default defineNuxtConfig({
|
|
21
|
+
modules: ["@anfo/nuxt-dialogs-plugin"],
|
|
22
|
+
|
|
23
|
+
// Optional — these are the defaults
|
|
24
|
+
dialogs: {
|
|
25
|
+
dir: "dialogs", // relative to srcDir
|
|
26
|
+
// pattern: /(Dialog|Drawer)\.vue$/,
|
|
27
|
+
// inheritNuxtApp: true,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Create a dialog component
|
|
33
|
+
|
|
34
|
+
Every `.vue` file whose name ends with `Dialog.vue` or `Drawer.vue` inside your `dir` becomes a key on the `dialogs` object. No tsconfig changes are needed — the module generates the type declarations for you.
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<!-- dialogs/ConfirmDialog.vue -->
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
import {
|
|
40
|
+
useDialogContext,
|
|
41
|
+
createDialogExpose,
|
|
42
|
+
type DialogExposed,
|
|
43
|
+
} from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
44
|
+
|
|
45
|
+
defineProps<{ message: string }>();
|
|
46
|
+
|
|
47
|
+
const { resolve, reject } = useDialogContext<boolean>();
|
|
48
|
+
|
|
49
|
+
defineExpose<DialogExposed<boolean>>(createDialogExpose<boolean>());
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<div class="overlay">
|
|
54
|
+
<div class="box">
|
|
55
|
+
<p>{{ message }}</p>
|
|
56
|
+
<button @click="resolve(true)">Confirm</button>
|
|
57
|
+
<button @click="resolve(false)">Cancel</button>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 3. Open dialogs from anywhere
|
|
64
|
+
|
|
65
|
+
`dialogs` is auto-imported — no import statement needed:
|
|
66
|
+
|
|
67
|
+
```vue
|
|
68
|
+
<script setup lang="ts">
|
|
69
|
+
const result = await dialogs.ConfirmDialog({ message: "Delete this item?" });
|
|
70
|
+
if (result.type === "resolve" && result.value) {
|
|
71
|
+
// confirmed
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Or chain callbacks
|
|
75
|
+
dialogs
|
|
76
|
+
.ConfirmDialog({ message: "Are you sure?" })
|
|
77
|
+
.resolve((value) => console.log("resolved:", value))
|
|
78
|
+
.reject((reason) => console.log("rejected:", reason));
|
|
79
|
+
</script>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Context inheritance — why dialogs "just work"
|
|
83
|
+
|
|
84
|
+
Each dialog is mounted into its own isolated `createApp()` instance. By default (`inheritNuxtApp: true`) the module captures the Nuxt app and clones its context — global components, directives and `provide`s — onto every dialog app. That means everything your Nuxt app registered is available inside dialogs automatically:
|
|
85
|
+
|
|
86
|
+
- **Pinia** stores (`@pinia/nuxt`)
|
|
87
|
+
- **i18n** (`@nuxtjs/i18n` — `$t`, translations)
|
|
88
|
+
- **UI libraries** (Element Plus, PrimeVue, Vuetify… registered via Nuxt plugins)
|
|
89
|
+
- **Global components and directives**
|
|
90
|
+
- **The `nuxtApp` itself** — `useNuxtApp()`, `useRoute()`… work inside dialogs
|
|
91
|
+
|
|
92
|
+
Set `inheritNuxtApp: false` to keep dialogs fully isolated (parity with plain Vite projects), and register exactly what you need with `configureDialogs()`:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
// plugins/dialogs.ts
|
|
96
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
97
|
+
configureDialogs({
|
|
98
|
+
use: [
|
|
99
|
+
(app) => {
|
|
100
|
+
app.config.globalProperties.$something = "...";
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Both plugin objects (`{ install(app) {} }`) and plain `(app) => void` functions are accepted.
|
|
108
|
+
|
|
109
|
+
## Module Options
|
|
110
|
+
|
|
111
|
+
| Option | Type | Default | Description |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `dir` | `string` | `"dialogs"` | Directory containing dialog components; relative paths resolve against `srcDir`. |
|
|
114
|
+
| `pattern` | `RegExp` | `/(Dialog\|Drawer)\.vue$/` | RegExp to identify which files are dialogs. |
|
|
115
|
+
| `inheritNuxtApp` | `boolean` | `true` | Dialog apps inherit the Nuxt app's context (components, directives, provides). |
|
|
116
|
+
|
|
117
|
+
## Auto-imports
|
|
118
|
+
|
|
119
|
+
| Name | From | Description |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `dialogs` | `virtual:dialogs` | Open dialogs — `dialogs.ConfirmDialog(props)`. |
|
|
122
|
+
| `useDialogContext` | `./runtime` | Get `{ resolve, reject }` inside a dialog component. |
|
|
123
|
+
| `createDialogExpose` | `./runtime` | Typed expose helper for `defineExpose`. |
|
|
124
|
+
| `configureDialogs` | `./runtime` | Register extra plugins for every dialog app. |
|
|
125
|
+
|
|
126
|
+
## Package Exports
|
|
127
|
+
|
|
128
|
+
| Specifier | Contents |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `@anfo/nuxt-dialogs-plugin` | Nuxt module |
|
|
131
|
+
| `@anfo/nuxt-dialogs-plugin/runtime` | Types, `useDialogContext`, `createDialogExpose`, `configureDialogs`, `DialogExposed` |
|
|
132
|
+
|
|
133
|
+
## SSR
|
|
134
|
+
|
|
135
|
+
Dialogs are DOM-only. Calling `dialogs.*` during server-side rendering is safe — it warns and settles as `{ type: "reject", reason }` instead of crashing the render. Open dialogs from event handlers or `onMounted`.
|
|
136
|
+
|
|
137
|
+
> Do not import `virtual:dialogs` from Nitro server code (`server/api`, `server/routes`) — the virtual module is only available in the app build.
|
|
138
|
+
|
|
139
|
+
## Project Structure
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
<srcDir>/
|
|
143
|
+
├── dialogs/ ← your dialog components (configurable)
|
|
144
|
+
│ ├── ConfirmDialog.vue
|
|
145
|
+
│ ├── AlertDialog.vue
|
|
146
|
+
│ └── UserDrawer.vue
|
|
147
|
+
└── nuxt.config.ts
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## How It Works
|
|
151
|
+
|
|
152
|
+
1. On startup the module registers a Vite plugin, a tiny runtime plugin (context capture), auto-imports and a type template.
|
|
153
|
+
2. The Vite plugin generates a virtual module (`virtual:dialogs`) that imports each component through the `#dialogs-components` alias and wraps it in `mountDialog()`.
|
|
154
|
+
3. `mountDialog()` creates an isolated `createApp()` instance per call, inherits the Nuxt app context, provides a `DialogController`, mounts it into a temporary `<div>`, and returns a Promise-based handle.
|
|
155
|
+
4. When the component calls `resolve(value)` or `reject(reason)`, the app is unmounted and the host element removed automatically.
|
|
156
|
+
5. A `.d.ts` type template is written into `.nuxt/` so every `dialogs.*` entry is typed end-to-end — props, return value, and callbacks. It regenerates when dialog files are added or removed during dev.
|
|
157
|
+
|
|
158
|
+
> See [SKILL.md](SKILL.md) for step-by-step examples covering all dialog patterns.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Skill Guide — Creating Dialog Components in Nuxt
|
|
2
|
+
|
|
3
|
+
This guide shows every pattern for building dialog and drawer components that work with `@anfo/nuxt-dialogs-plugin`. All types and composables are auto-imported in Nuxt — explicit imports from `@anfo/nuxt-dialogs-plugin/runtime` also work and are shown here for clarity.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Runtime API Reference
|
|
8
|
+
|
|
9
|
+
Import from `@anfo/nuxt-dialogs-plugin/runtime` (or rely on auto-imports):
|
|
10
|
+
|
|
11
|
+
| Export | Auto-imported | Description |
|
|
12
|
+
| ------------------------- | ------------- | --------------------------------------------------------------------------------- |
|
|
13
|
+
| `dialogs` | ✅ | Open dialogs — `dialogs.ConfirmDialog(props)` (virtual module `virtual:dialogs`) |
|
|
14
|
+
| `useDialogContext<T>()` | ✅ | Composable — returns `{ resolve, reject }` inside a dialog component |
|
|
15
|
+
| `createDialogExpose<T>()` | ✅ | Helper — creates the typed expose object (shorthand for `{} as DialogExposed<T>`) |
|
|
16
|
+
| `configureDialogs()` | ✅ | Register extra Vue plugins to `app.use()` on every dialog app |
|
|
17
|
+
| `DialogExposed<T>` | — type | Marker type — put in `defineExpose<>` to declare the resolve value type |
|
|
18
|
+
| `DialogController<T>` | — type | `{ resolve: DialogResolve<T>, reject: DialogReject }` |
|
|
19
|
+
| `DialogSettledResult<T>` | — type | Union of `DialogResolvedResult<T>` and `DialogRejectedResult` |
|
|
20
|
+
| `DialogResolvedResult<T>` | — type | `{ type: "resolve" }` or `{ type: "resolve"; value: T }` |
|
|
21
|
+
| `DialogRejectedResult` | — type | `{ type: "reject"; reason?: unknown }` |
|
|
22
|
+
| `DialogAppPlugin` | — type | Alias of Vue's `Plugin` — a plugin object or a function taking the app |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Nuxt setup
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// nuxt.config.ts
|
|
30
|
+
export default defineNuxtConfig({
|
|
31
|
+
modules: ["@anfo/nuxt-dialogs-plugin"],
|
|
32
|
+
|
|
33
|
+
// Optional — defaults shown
|
|
34
|
+
dialogs: {
|
|
35
|
+
dir: "dialogs", // relative to srcDir
|
|
36
|
+
// pattern: /(Dialog|Drawer)\.vue$/,
|
|
37
|
+
// inheritNuxtApp: true,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Place dialog components in `<srcDir>/dialogs/` (or configure `dir`). Files ending in `Dialog.vue` or `Drawer.vue` become keys on the `dialogs` object. Types are generated into `.nuxt/` automatically — no tsconfig changes needed.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Context inheritance
|
|
47
|
+
|
|
48
|
+
By default every dialog app **inherits the Nuxt app's context** — global components, directives and provides. Inside dialog components this means:
|
|
49
|
+
|
|
50
|
+
- Pinia stores work (`@pinia/nuxt`)
|
|
51
|
+
- `$t` / i18n works (`@nuxtjs/i18n`)
|
|
52
|
+
- UI library components registered in Nuxt work
|
|
53
|
+
- `useNuxtApp()`, `useRoute()` work
|
|
54
|
+
|
|
55
|
+
No wiring needed. To opt out, set `inheritNuxtApp: false` and register exactly what you need with `configureDialogs()`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// plugins/dialogs.ts
|
|
59
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
60
|
+
configureDialogs({
|
|
61
|
+
use: [
|
|
62
|
+
// plain functions and plugin objects both work
|
|
63
|
+
(app) => {
|
|
64
|
+
app.config.globalProperties.$t = translate;
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Pattern 1 — Simple dialog, no return value
|
|
74
|
+
|
|
75
|
+
The simplest case: open, the user clicks a button, dialog closes.
|
|
76
|
+
|
|
77
|
+
```vue
|
|
78
|
+
<!-- dialogs/AlertDialog.vue -->
|
|
79
|
+
<script setup lang="ts">
|
|
80
|
+
import { useDialogContext } from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
81
|
+
|
|
82
|
+
defineProps<{ message: string }>();
|
|
83
|
+
|
|
84
|
+
const { resolve } = useDialogContext();
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<template>
|
|
88
|
+
<div class="overlay">
|
|
89
|
+
<div class="box">
|
|
90
|
+
<p>{{ message }}</p>
|
|
91
|
+
<button @click="resolve()">OK</button>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</template>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```vue
|
|
98
|
+
<!-- Caller (auto-imported `dialogs`) -->
|
|
99
|
+
<script setup lang="ts">
|
|
100
|
+
await dialogs.AlertDialog({ message: "File saved." });
|
|
101
|
+
// resolves with { type: "resolve" } — no value
|
|
102
|
+
</script>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Pattern 2 — Dialog that returns a typed value
|
|
108
|
+
|
|
109
|
+
Use `defineExpose<DialogExposed<T>>` to declare what `resolve()` carries. The generic `T` flows all the way to the caller's return type.
|
|
110
|
+
|
|
111
|
+
```vue
|
|
112
|
+
<!-- dialogs/ConfirmDialog.vue -->
|
|
113
|
+
<script setup lang="ts">
|
|
114
|
+
import {
|
|
115
|
+
useDialogContext,
|
|
116
|
+
createDialogExpose,
|
|
117
|
+
type DialogExposed,
|
|
118
|
+
} from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
119
|
+
|
|
120
|
+
defineProps<{
|
|
121
|
+
message: string;
|
|
122
|
+
confirmLabel?: string;
|
|
123
|
+
}>();
|
|
124
|
+
|
|
125
|
+
const { resolve } = useDialogContext<boolean>();
|
|
126
|
+
|
|
127
|
+
// Declare the resolve type — T = boolean
|
|
128
|
+
defineExpose<DialogExposed<boolean>>(createDialogExpose<boolean>());
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<template>
|
|
132
|
+
<div class="overlay">
|
|
133
|
+
<div class="box">
|
|
134
|
+
<p>{{ message }}</p>
|
|
135
|
+
<button @click="resolve(true)">{{ confirmLabel ?? "Confirm" }}</button>
|
|
136
|
+
<button @click="resolve(false)">Cancel</button>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</template>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// Caller — result.value is typed as boolean | undefined
|
|
144
|
+
const result = await dialogs.ConfirmDialog({ message: "Delete item?" });
|
|
145
|
+
if (result.type === "resolve" && result.value) {
|
|
146
|
+
await deleteItem();
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Pattern 3 — Dialog with reject
|
|
153
|
+
|
|
154
|
+
Call `reject(reason)` for explicit cancellation that the caller can distinguish from a normal close.
|
|
155
|
+
|
|
156
|
+
```vue
|
|
157
|
+
<!-- dialogs/PromptDialog.vue -->
|
|
158
|
+
<script setup lang="ts">
|
|
159
|
+
import { ref } from "vue";
|
|
160
|
+
import {
|
|
161
|
+
useDialogContext,
|
|
162
|
+
createDialogExpose,
|
|
163
|
+
type DialogExposed,
|
|
164
|
+
} from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
165
|
+
|
|
166
|
+
defineProps<{ label: string }>();
|
|
167
|
+
|
|
168
|
+
const { resolve, reject } = useDialogContext<string>();
|
|
169
|
+
const input = ref("");
|
|
170
|
+
|
|
171
|
+
defineExpose<DialogExposed<string>>(createDialogExpose<string>());
|
|
172
|
+
</script>
|
|
173
|
+
|
|
174
|
+
<template>
|
|
175
|
+
<div class="overlay">
|
|
176
|
+
<div class="box">
|
|
177
|
+
<label>{{ label }}</label>
|
|
178
|
+
<input v-model="input" @keydown.enter="resolve(input)" />
|
|
179
|
+
<button @click="resolve(input)">OK</button>
|
|
180
|
+
<button @click="reject('cancelled')">Cancel</button>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</template>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// Caller — chain style
|
|
188
|
+
dialogs
|
|
189
|
+
.PromptDialog({ label: "Enter a name" })
|
|
190
|
+
.resolve((name) => console.log("Got:", name))
|
|
191
|
+
.reject((reason) => console.log("Cancelled:", reason));
|
|
192
|
+
|
|
193
|
+
// Caller — await style
|
|
194
|
+
const result = await dialogs.PromptDialog({ label: "Enter a name" });
|
|
195
|
+
if (result.type === "resolve") {
|
|
196
|
+
console.log(result.value); // string | undefined
|
|
197
|
+
} else {
|
|
198
|
+
console.log(result.reason); // "cancelled"
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Pattern 4 — Drawer
|
|
205
|
+
|
|
206
|
+
Files ending in `Drawer.vue` are matched by the default pattern and work identically to dialogs.
|
|
207
|
+
|
|
208
|
+
```vue
|
|
209
|
+
<!-- dialogs/UserDrawer.vue -->
|
|
210
|
+
<script setup lang="ts">
|
|
211
|
+
import { useDialogContext } from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
212
|
+
|
|
213
|
+
defineProps<{ userId: string }>();
|
|
214
|
+
const { resolve } = useDialogContext();
|
|
215
|
+
</script>
|
|
216
|
+
|
|
217
|
+
<template>
|
|
218
|
+
<aside class="drawer">
|
|
219
|
+
<p>User: {{ userId }}</p>
|
|
220
|
+
<button @click="resolve()">Close</button>
|
|
221
|
+
</aside>
|
|
222
|
+
</template>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
await dialogs.UserDrawer({ userId: "abc123" });
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Pattern 5 — Dialog using Pinia / global components
|
|
232
|
+
|
|
233
|
+
Thanks to context inheritance, dialogs can use anything registered in the Nuxt app — e.g. a Pinia store and UI-library components:
|
|
234
|
+
|
|
235
|
+
```vue
|
|
236
|
+
<!-- dialogs/CartDialog.vue -->
|
|
237
|
+
<script setup lang="ts">
|
|
238
|
+
import { useCartStore } from "~/stores/cart";
|
|
239
|
+
import { useDialogContext } from "@anfo/nuxt-dialogs-plugin/runtime";
|
|
240
|
+
|
|
241
|
+
const cart = useCartStore();
|
|
242
|
+
const { resolve } = useDialogContext();
|
|
243
|
+
</script>
|
|
244
|
+
|
|
245
|
+
<template>
|
|
246
|
+
<div class="overlay">
|
|
247
|
+
<div class="box">
|
|
248
|
+
<p>{{ cart.items.length }} items — {{ cart.total }}</p>
|
|
249
|
+
<button @click="resolve()">Done</button>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
</template>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## SSR behavior
|
|
258
|
+
|
|
259
|
+
Dialogs are DOM-only. Calling `dialogs.*` during SSR warns and settles as `{ type: "reject", reason }` — it never crashes the server render. Open dialogs from event handlers or `onMounted`. Don't import `virtual:dialogs` from Nitro server code (`server/api`, `server/routes`).
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Summary
|
|
264
|
+
|
|
265
|
+
| Task | How |
|
|
266
|
+
| ------------------------ | -------------------------------------------------------------------------- |
|
|
267
|
+
| Get resolve/reject | `const { resolve, reject } = useDialogContext<T>()` |
|
|
268
|
+
| Declare return type | `defineExpose<DialogExposed<T>>(createDialogExpose<T>())` |
|
|
269
|
+
| Open from app code | `dialogs.MyDialog(props)` — auto-imported, or import from `virtual:dialogs` |
|
|
270
|
+
| Await result | `const result = await dialogs.MyDialog(props)` |
|
|
271
|
+
| Chain callbacks | `.resolve(cb).reject(cb)` |
|
|
272
|
+
| Share Pinia / UI libs | Automatic via `inheritNuxtApp` (default); extras via `configureDialogs()` |
|
|
273
|
+
|
|
274
|
+
The module auto-regenerates the virtual module and types whenever you add or remove dialog files during dev — no manual registration needed.
|