notiwind icon indicating copy to clipboard operation
notiwind copied to clipboard

use in nuxt

Open ErfanBahramali opened this issue 1 year ago • 3 comments

Hi I want to use notiwind in nuxtjs First, I installed it and registered it as a plugin Second, I added notification components as Notification.vue file in components Third, I used it in a page (example notiwind.vue). But I encountered the errors that you can see below

Sources:

install:

npm i notiwind -D

Notification.client.js:

// ~/plugins/Notification.client.js

import notifications from 'notiwind'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(notifications)
})

Notification.vue:


<!-- ~/components/Notification.vue -->

<template>
    <div>
        <NotificationGroup group="sucess-top" position="top">
            <div class="z-50 fixed inset-0 flex items-start justify-start p-6 px-4 py-6 pointer-events-none">
                <div class="w-full max-w-sm">

                    <Notification v-slot="{ notifications, close }" enter="ease-out duration-300 transition" enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4" enter-to="translate-y-0 opacity-100 sm:translate-x-0" leave="transition ease-in duration-500" leave-from="opacity-100" leave-to="opacity-0" move="transition duration-500" move-delay="delay-300">
                        <div v-for="notification in notifications" :key="notification.id" class="w-full max-w-sm mt-4 overflow-hidden bg-white rounded-lg shadow-lg pointer-events-auto ring-1 ring-black ring-opacity-5">
                            <div class="p-4">

                                <div class="flex items-start">
                                    <div class="shrink-0">
                                        <svg class="w-6 h-6 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                                        </svg>
                                    </div>

                                    <div class="mr-3 w-0 flex-1 pt-0.5">
                                        <p class="font-semibold text-gray-800">
                                            {{ notification.title }}
                                        </p>
                                        <p class="text-sm font-semibold text-gray-500">
                                            {{ notification.text }}
                                        </p>
                                    </div>

                                    <div class="flex mr-4 shrink-0">
                                        <button class="inline-flex text-gray-400 bg-white rounded-md hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400" @click="close(notification.id)">
                                            <span class="sr-only">Close</span>
                                            <svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                                                <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
                                            </svg>
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </Notification>
                </div>
            </div>
        </NotificationGroup>
    </div>
</template>

notiwind.vue:


<!-- ~/pages/notiwind.vue -->

<script setup>

import { notify } from 'notiwind';

notify({
    group: "sucess-top",
    title: "sucess",
    text: "Everything is ok",
}, -1);

</script>

<template>
    <Notification />
</template>

Errrors (In Terminal):

[Vue warn]: Failed to resolve component: NotificationGroup
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Failed to resolve component: NotificationGroup
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.

Errors (In Inspect Console):

image

Apparently, it does't recognize the NotificationGroup at all What's the problem and the solution ?

ErfanBahramali avatar Oct 10 '23 22:10 ErfanBahramali

I had the same problem with nuxt3, using vite + vue 3 works fine.

paulocastellano avatar Oct 11 '23 16:10 paulocastellano

it's work for me in nuxt3

https://github.com/emmanuelsw/notiwind#typescript

ErfanBahramali avatar Oct 12 '23 09:10 ErfanBahramali

Here is the wrapper component (ToastNotifications.vue) I am using with Nuxt

<script setup lang="ts">
import { NotificationGroup, Notification } from "notiwind"
import ToastNotification from "@/components/ToastNotification.vue"
</script>

<template>
  <!-- global notification region, rendered permanently in document -->
  <NotificationGroup>
    <div
      aria-live="assertive"
      class="pointer-events-none fixed z-50 inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6"
    >
      <div class="flex w-full flex-col items-center space-y-4 sm:items-end">
        <!-- notification data is fed through the slot below -->
        <Notification
          v-slot="{ notifications, close }"
          enter="transform ease-out duration-300 transition"
          enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
          enter-to="translate-y-0 opacity-100 sm:translate-x-0"
          leave="transition ease-in duration-100"
          leave-from="opacity-100"
          leave-to="opacity-0"
        >
          <ToastNotification
            v-for="notification in notifications"
            :key="notification.id"
            :notification="notification"
            :close="close"
          />
        </Notification>
      </div>
    </div>
  </NotificationGroup>
</template>

ToastNotification is my custom component I use to draw the notifications.

This component is included in my primary layout like this:

<script setup>
import SiteHeader from "@/components/SiteHeader.vue"
import ToastNotifications from "@/components/ToastNotifications.vue"
</script>

<template>
  <Html class="h-full bg-gray-50" />
  <Body class="h-full" />

  <div class="min-h-full">
    <ToastNotifications />
    <SiteHeader />

    <main>
      <slot />
    </main>
  </div>
</template>

My nuxt plugin looks like this:

import { defineNuxtPlugin } from "#app"
import Notifications, { notify } from "notiwind"

type NotificationOptions = {
  group?: string
  title: string
  text: string
  type?: "info" | "success" | "warn" | "error"
}

// core method, use with $toast("foo")
function notifyFlexible(
  info: string | NotificationOptions,
  displayFor?: number,
  type?: "info" | "success" | "warn" | "error"
) {
  if (typeof info === "string") {
    notify({ title: info, type }, displayFor)
  } else {
    notify(info, displayFor)
  }
}

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(Notifications)
  return {
    provide: {
      toast: notifyFlexible,
    },
  }
})

The provide line includes the name I'm using for access in my components (for me, $toast). I use it like this:

const { $toast } = useNuxtApp()
$toast("hello world")

nextmat avatar Nov 23 '23 00:11 nextmat