Skip to content

Commit

Permalink
feat: add iziToast integration with auto-imported composable
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenjason89 committed Jan 19, 2025
1 parent e3376b6 commit b8cf45b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 13 deletions.
7 changes: 7 additions & 0 deletions playground/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@
</template>

<script setup>
const toast = useToast()
// Show a toast for 30 seconds
toast.success({
title: 'Hooray!',
message: 'iziToast is awesome!',
})
</script>
1 change: 0 additions & 1 deletion playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ export default defineNuxtConfig({
modules: ['../src/module'],
devtools: { enabled: true },
compatibilityDate: '2025-01-20',
myModule: {},
})
29 changes: 19 additions & 10 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
import { defineNuxtModule, addPlugin, createResolver, addImports } from '@nuxt/kit'

// Module options TypeScript interface definition
export interface ModuleOptions {}
export interface ModuleOptions {
composableName?: string
}

export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'my-module',
configKey: 'myModule',
name: 'nuxt-toast',
configKey: 'iziToast',
compatibility: { nuxt: '>=3.0.0' },
},
// Default configuration options of the Nuxt module
defaults: {},
setup(_options, _nuxt) {

setup(options, _nuxt) {
const resolver = createResolver(import.meta.url)

// Do not add the extension since the `.ts` will be transpiled to `.mjs` after `npm run prepack`
addPlugin(resolver.resolve('./runtime/plugin'))
addPlugin({
src: resolver.resolve('./runtime/plugin'),
mode: 'client',
})

addImports({
name: 'useToast',
as: options.composableName ?? 'useToast',
from: resolver.resolve('./runtime/composables/useToast'),
})
},
})
9 changes: 9 additions & 0 deletions src/runtime/composables/useToast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type Toast from '../types/IziToast'
import { useNuxtApp } from '#app'

export function useToast(): Toast {
if (import.meta.server) {
return new Proxy({} as Toast, { get: () => () => {} }) // SSR Safe
}
return useNuxtApp().$iziToast
}
42 changes: 40 additions & 2 deletions src/runtime/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
import type { IziToastSettings } from 'izitoast'
import iziToast from 'izitoast'
import type Toast from './types/IziToast.ts'
import { defineNuxtPlugin } from '#app'
import 'izitoast/dist/css/iziToast.min.css'

export default defineNuxtPlugin((_nuxtApp) => {
console.log('Plugin injected by my-module!')
export default defineNuxtPlugin(() => {
const THEMES = {
info: { color: 'blue', icon: 'ico-info' },
success: { color: 'green', icon: 'ico-success' },
warning: { color: 'orange', icon: 'ico-warning' },
error: { color: 'red', icon: 'ico-error' },
question: { color: 'yellow', icon: 'ico-question' },
}

return {
provide: {
iziToast: {
...iziToast,
hideToast(title: string, message: string, status: keyof typeof THEMES) {
const color = THEMES[status].color
const newId = btoa(encodeURIComponent(`${title}${message}${color}`)).replace(/=/g, '')

document
.querySelectorAll(`.iziToast#${newId}`)
.forEach(
element =>
element instanceof HTMLDivElement
&& iziToast.hide({ title, message, id: newId }, element, 'replaced'),
)
},
data(data: IziToastSettings & { status: keyof typeof THEMES }) {
iziToast.show({
...data,
color: THEMES[data?.status]?.color,
icon: THEMES[data?.status]?.icon,
timeout: data.timeout ?? 2500,
})
},
} as Toast,
},
}
})
6 changes: 6 additions & 0 deletions src/runtime/types/IziToast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { IziToast, IziToastSettings } from 'izitoast'

export default interface Toast extends IziToast {
hideToast: (title: string, message: string, status: string) => void
data: (data: IziToastSettings & { status: string }) => void
}

0 comments on commit b8cf45b

Please sign in to comment.