Closed peterbud closed 12 months ago
Hi Peter. Yes, I released a new major version, therefore there are some breaking changes in the API.
I was planning on writing a migration guide, but I think the best thing to do is to read the new documentation and then adapt your code.
Regarding your issue, configuration props have been moved to plugin options, which in your case are now located in plugins/notivue.client.ts:
import { notivue } from 'notivue'
export default defineNuxtPlugin(({ vueApp }) => {
vueApp.use(notivue, {
pauseOnHover: true
// ... Other options
})
})
If you need to update the above options dynamically, use the useNotivue
composable:
<script setup>
import {Â useNotivue } from 'notivue'
const config = useNotivue()
function updateConfig() {
config.position.value = 'top-left'
config.pauseOnTouch.value = true
}
</script>
In addition to that, there are new configuration options such as pauseOnTabChange
and limit
. The options
prop, has been renamed to notifications
and can be found in the configuration object as well.
But the most important change is that starting from v1.0.0 <Notivue />
exposes the notification item via v-slot
making a hundred times easier using custom components:
<script setup>
import { Notivue, Notifications } from 'notivue'
</script>
<template>
<Notivue v-slot="item">
<Notifications :item="item" />
<!-- Or use your component in place of Notifications -->
</Notivue>
</template>
Please take a look at the new documentation, which contains all the information you need.
Of course, let me know if you need any further assistance.
Hi @smastrom , many thanks for the help - I have successfully managed to update my custom notification component, and it works.
The only problem still is the exported types are not available:
Is there any chance to fix them?
Another question, which I cannot find in the new documentation was how to make a composable which renders a custom component?
There was something like this in the previous doc:
const methods = ['success', 'error', 'warning', 'info'] as const
methods.forEach((method) => {
customPush[method] = ({ props = {}, ...options }) =>
push[method]({
...options,
render: {
component: () => Toast,
props: ({ notivueProps }) => ({
...notivueProps,
...props,
}),
},
})
})
I'm not sure what is the designated way to pass all the props to the custom component? Maybe if you have an example included in the doc, that would be a great help I believe.
Hi @peterbud, types are exported. The import name is NotivueSlot
and not NotivueItem
, my bad for not updating the documentation, which I did now.
Regarding the other question, as I told you in the previous answer, v1 brings breaking changes on how custom components are handled.
I'll try to write an example here, but you can find it on the docs section as well.
Starting from v1, the render
property of the UserPushOptions
interface (which is the object you pass as only parameter to push) doesn't exist anymore. Instead, custom components are passed as default slot inside <Notivue />
. This keeps your custom components in a single place and is a way better DX as being more declarative.
app.vue
<script setup lang="ts">
import { Notivue } from 'notivue';
import Custom from './components/Custom.vue';
</script>
<template>
<ClientOnly
<Notivue v-slot="item">
<Custom :item="item" />
</Notivue>
</template>
Out of curiosity, you can try to see the data that are exposed by serializing the notification item (NotivueSlot
interface):
<template>
<Notivue v-slot="item">
<div> {{ JSON.stringify(item) }} </div>
</Notivue>
</template>
This object contains the data needed to render the notification content.
Always starting from v1, UserPushOptions
interface has now a props
property which can be used to pass any kind of data you want to include in the notification object (NotivueSlot
).
So let's say you call push with:
push.success({
message: 'This is a success message',
props: {
customName: 'Giovanni',
isCriticalToast: true,
},
})
You can now get the value of item.props.customName
inside your custom component along with item.message
, item.type
etc.
According to that, you can use the same props to render different components, for example:
<script setup>
import { Notivue, Notifications } from 'notivue'
import MyToast from './MyToast.vue'
import MyOtherToast from './MyOtherToast.vue'
</script>
<template>
<ClientOnly>
<Notivue v-slot="item">
<MyToast
v-if="item.props.isCriticalToast"
:item="item"
/>
<MyOtherToast
v-else-if="item.props.isOtherToast"
:item="item"
/>
<!-- Use default notifications -->
<Notifications
v-else
:item="item"
/>
</Notivue>
</ClientOnly>
</template>
So regarding your specific case, you don't need anymore to create a custom composable unless you really want to keep things more organized, for example to avoid passing always the same props:
import { usePush, type NotificationOptions } from 'notivue'
type MyCustomProps = {
isMyCustomToast: boolean
customerName: string
// Other props...
}
type CustomPushOptions = Partial<NotificationOptions> & {
props?: Partial<MyCustomProps>
}
const methods = ['success', 'error', 'warning', 'info'] as const
type CustomPush = {
[K in (typeof methods)[number]]: (options: CustomPushOptions) => ReturnType<Push[K]>
}
export function useCustomPush() {
const push = usePush()
const customPush = {} as CustomPush
methods.forEach((method) => {
customPush[method] = ({ props = {}, ...options }) =>
push[method]<MyCustomProps>({
...options, // Some dynamic options
title: 'New Message Request', // Some default options
props: {
...props, // Some dynamic props
isMyCustomToast: true, // Some default props
},
})
})
return customPush
}
Then call and use it with the same, identical API:
const customPush = useCustomPush()
customPush.error({
message: 'Something went wrong.',
props: {
customerName: 'Marco Aurelio',
},
})
Let me know if everything's clear and if you need further assistance.
Simone
Many thanks - perfect!!
Updating to v 1.0.2 results the following error:
[Vue warn]: Extraneous non-props attributes (position, pause-on-hover) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
With version 0.9.4 it works, and no error is visible.
Was there any change between the two versions? Position and pause-on-hover is now not the props of the component?
I'm using nuxt 3.6.1