Skip to content

Commit a084ccc

Browse files
feat: add useNinjaToaster composable
1 parent 0fb08d2 commit a084ccc

File tree

5 files changed

+87
-10
lines changed

5 files changed

+87
-10
lines changed

.playground/app.vue

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
import { h } from 'vue'
33
import CustomToast from './components/CustomToast.vue'
44
import AdvancedToast from './components/AdvancedToast.vue'
5-
import { useNuxtApp } from '#app'
65
7-
const { $nt } = useNuxtApp()
6+
const $nt = useNinjaToaster()
87
let i = 0
98
109
function showBasicToast() {
@@ -84,6 +83,35 @@ async function showAdvancedToast() {
8483
8584
toast.el.focus()
8685
}
86+
87+
function showGlobalToast() {
88+
$nt.showComponent('GlobalToast', {
89+
props: {
90+
type: 'basic',
91+
message: 'Hello from GlobalToast module playground!'
92+
},
93+
options: {
94+
theme: {
95+
transition: {
96+
name: 'toaster'
97+
},
98+
maxToasts: 5,
99+
containerId: 'nt-container-bottom-right',
100+
containerClass: [
101+
'absolute',
102+
'inset-0',
103+
'pointer-events-none',
104+
'p-4',
105+
'flex',
106+
'flex-col-reverse',
107+
'items-start',
108+
'gap-2'
109+
],
110+
wrapperClass: 'pointer-events-auto cursor-pointer'
111+
}
112+
}
113+
})
114+
}
87115
function clearAllToast() {
88116
$nt.clearAll()
89117
}
@@ -113,6 +141,12 @@ function clearTopLeftToast() {
113141
>
114142
show advanced toast
115143
</button>
144+
<button
145+
class="m-1 rounded border border-slate-200 px-2 py-1"
146+
@click="showGlobalToast"
147+
>
148+
show global toast
149+
</button>
116150
<button
117151
class="m-1 rounded border border-slate-200 px-2 py-1"
118152
@click="clearTopLeftToast"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
const props = defineProps<{
3+
type?: 'basic' | 'custom' | 'advanced'
4+
message?: string
5+
}>()
6+
</script>
7+
8+
<template>
9+
<div class="rounded bg-green-600 p-4 text-white">
10+
<p>Hello global, {{ props.message }}</p>
11+
</div>
12+
</template>

src/module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@ export default defineNuxtModule<ModuleOptions>({
3636
})
3737

3838
if (options.installPlugin) {
39+
addImports({
40+
name: 'useNinjaToaster',
41+
as: 'useNinjaToaster',
42+
from: resolve(runtimeDir, 'composables/useNinjaToaster')
43+
})
3944
addPlugin(resolve(runtimeDir, 'plugin'))
4045
}
4146
}
4247
})
4348

4449
declare module '@nuxt/schema' {
4550
interface AppConfigInput {
46-
/** nuxt-icon configuration */
4751
toaster?: NinjaToasterBaseProps
4852
}
49-
}
53+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
type NinjaToasterInstance = ReturnType<typeof createNinjaToaster>
3+
4+
export function useNinjaToaster() {
5+
const { $nt } = useNuxtApp()
6+
return $nt as NinjaToasterInstance
7+
}

src/runtime/create.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import { type App, h, render } from 'vue'
1+
import { type App, type VNode, h, render } from 'vue'
22
import { defu } from 'defu'
33

44
import type { NinjaToasterTheme, NinjaToasterBaseProps, NinjaToasterProps, NinjaToasterShow } from '../types'
55
import type { NinjaToasterRenderQueue } from './queue'
66
import { type NinjaToastEventBus, createEventBus } from './events'
77
import NinjaToaster from './components/NinjaToaster'
88

9-
// @ts-ignore
10-
import { useAppConfig, useNuxtApp } from '#imports'
9+
import { resolveComponent, useAppConfig, useNuxtApp } from '#imports'
10+
import type * as _AllComponents from '#components'
11+
12+
type ComponentProps<T> = T extends keyof typeof _AllComponents
13+
? InstanceType<(typeof _AllComponents)[T]>['$props']
14+
: undefined
1115

1216
function createElement() {
1317
// @ts-ignore
@@ -54,9 +58,24 @@ export function createNinjaToaster(
5458
const events = createEventBus()
5559
const queues: Map<string, NinjaToasterRenderQueue> = new Map()
5660

57-
function show(options: NinjaToasterProps | string | number) {
58-
const appConfigProps: NinjaToasterBaseProps = (useAppConfig() as any)
59-
.toaster
61+
function showComponent<T extends keyof typeof _AllComponents>(name: T, {
62+
props,
63+
children,
64+
options,
65+
}: {
66+
props?: ComponentProps<T>,
67+
children?: any
68+
options?: Omit<NinjaToasterProps, 'content'>
69+
}) {
70+
const content = () => h(resolveComponent(name), props, children)
71+
return show({
72+
...options,
73+
content,
74+
})
75+
}
76+
77+
function show(options: NinjaToasterProps | string | number | (() => VNode)) {
78+
const appConfigProps = useAppConfig()?.toaster as NinjaToasterBaseProps
6079
const app = useNuxtApp().vueApp
6180
const userProps =
6281
typeof options === 'string' ||
@@ -119,6 +138,7 @@ export function createNinjaToaster(
119138

120139
return {
121140
show,
141+
showComponent,
122142
clearAll,
123143
clear
124144
}

0 commit comments

Comments
 (0)