Releases: smastrom/notivue
v2.4.5
Release notes
The next patch release updates the Vue version used to compile Notivue's components and ships a full rework of the Astro implementation without any API changes.
Core
Since Vue v3.5 entered the RC stage last week and v3.4 downloads surpassed by at least 4 times the downloads of v3.3, components are now compiled using the latest v3.4 stable version, upgrading from v3.3 as Notivue is always compiled with the previous most-downloaded minor release of Vue.
Astro Module
By design, Astro creates a new Vue app for each Vue island inserted in the markup of an Astro component or page. This means that if a plugin such as notivue
is installed in pages/_app.js/ts
and 5 Vue components are imported in the Astro markup, Notivue will be installed in all of the 5 Vue apps created by Astro when rendering the island in isolation. This started causing some hydration and View Transitions related issues since Astro v4.
Starting from this release, only one Vue app is created when installing Notivue as the store is now provided by simply calling provide()
in the <Notivue />
setup function instead of app.provide
during plugin installation.
This ensures that the notification state is always retained between page navigation and that by calling push
, notifications are dispatched, received, and processed by the same Vue app.
In order to keep the API consistent with Vue/Nuxt and previous versions it is still needed to call createNotivue
in _app.js/ts
which does nothing than exposing the initial config to the Vue app.
Check the docs on how to implement Notivue with Astro's View Transitions.
v2.4.4
v2.4.0 - v2.4.3
Release Notes
The next minor release brings a new exciting feature, plently of improvements and a non-breaking but important change to the API.
At this point, I believe Notivue is feature-complete and most likely there won't be new features in future releases besides improvements and fixes.
New: useNotivueInstance
Consumers can now fully control the Notivue instance by stopping and restarting it.
In .vue
components:
<script setup lang="ts">
import { useNotivueInstance } from 'notivue'
const { isRunning, startInstance, stopInstance } = useNotivueInstance()
</script>
In any other module:
import { startInstance, stopInstance } from 'notivue'
This allows the users of an app, for example, to properly enable and disable notifications in total autonomy.
Before this release, this was not "officially" supported and it could be achieved for example, by mounting/unmounting <Notivue />
(e.g. using v-if
) but this was not optimal as it would have not stopped the store from "working" in the background, processing unwanted notifications and wasting resources.
This is now done the right way: when the instance is stopped, the whole store is reset, any watcher is detached, any update to the config either via direct setter or via update()
is gracefully proxied without throwing errors. Same for push
, which is made no-op when the instance is stopped.
Finally, notivue
can now be initialized with a startOnCreation
option (which defaults to true
):
import { createNotivue } from 'notivue'
const notivue = createNotivue({
startOnCreation: false,
// Other options
})
If set to false
, Notivue won't be started when the app is mounted.
This can be useful to make sure that for some users Notivue is never enabled or to only start it when the environment is ready:
import { updateConfig, startInstance } from 'notivue'
fetch('/api/user-preferences')
.then((res) => res.json())
.then((data) => {
if (data.notifications.isEnabled) {
startInstance()
updateConfig(data.notifications.config)
}
})
Change: Add transition
config property and disable automatic transition property detection
Before this release Notivue automatically computed the transition property added to the containers when repositioning them by "reading" the animationDuration
and animationTimingFunction
properties of the enter animation as soon as the first notification was rendered.
This logic required about 100 lines of code and added some complexity that could definitely be avoided as the majority of users are not customizing animations at all. This also made the package smaller and more efficient.
Starting from this release, Notivue won't compute anymore the transition property automatically, instead it should be defined manually in the configuration if using custom animations.
const notivue = createNotivue({
transition: 'transform 200ms ease-out',
})
Check the docs website for more info.
Improvement: Fine-tune repositioning
Notivue handles repositioning of the notifications using a custom approach via CSS transitions and inline styles. Internally, the store includes a method named updatePositions
that is called to compute and apply those styles everytime the notifications must be repositioned (creation, clearing, destroy, size-change, etc).
Before this release, such method was called a couple of times more than necessary on both creation and clearing, creating some unnecessary overhead.
By adding a tiny logic that keeps track of the lifecycle events (creation, clearing and destruction), I was able to move the updatePositions
logic to a single place of the store in order to make sure that repositoning now happens only once per each of those events.
Improvement: Fine-tune ResizeObserver
Notivue uses the ResizeObserver
API to keep track of the size of the containers and to reposition them if needed, for example, when the content of a notification is updated dynamically, all the notifications must be repositioned.
Before this release, the ResizeObserver
callback would have repositioned the notifications when they were about to be destroyed, if their size never changed. This was totally unnecessary as it was already handled (as explained in the previous section) and it has been taken care of.
Improvement: Fine-tune pauseOnTabChange: false
Before this release, if pauseOnTabChange
was disabled in the config, the notifications would have been immediately destroyed when the window was blurred.
I realized that this not optimal as an user would expect the notifications timeouts to be kept alive and running.
This has been taken care of and the behavior when pauseOnTabChange
is disabled is now basically the same as if the user din't left the app.
v2.3.0 - v2.3.2
Release notes
The next minor release of Notivue introduces a couple of cool features plus some improvements:
- New (Core): Add
avoidDuplicates
config option - New (Core): Expose
isStreamPaused
internal signal - New (Built-in Notifications): Add
NotificationProgress
drop-in component - Refactor (Core): Use window's
focus/blur
events instead ofvisibilityChange
- Improve (Core): Remove workaround for lightningcss keyframes minification (fixed upstream)
- Improve (Core): Add singular-named import aliases for any exported CSS file
- Fix (Built-in Notifications): Fix setting fallback accent color when computing
--nv-accent
CSS variable
The above new features can be summarized in this short video:
preview-2.3.0.mov
avoidDuplicates
config option
It is now possible to prevent the creation of notifications already displayed in the stream or already awaiting in the queue (duplicates).
I've found this feature extremely useful in scenarios where the same notification might be repeatedly created (external services errors, frequently updated settings), creating unnecessary noise in the UI.
Since the whole implementation required just a few lines of code, I believed it was a good trade-off implementing it.
While this option is disabled by default, it can be enabled by setting avoidDuplicates
to true
in Notivue's config:
const notivue = createNotivue({
avoidDuplicates: true
})
Once enabled, if a notification like the following is pushed to the stream:
push.error({
title: 'Error',
message: 'There was an error sending your message, please try again.'
})
...and a notification with the same title
, message
and type
is already displayed, Notivue will immediately make screen readers announce it again without rendering a new one.
Then, it will replace the remaining duration of the visible notification with the duration of the duplicate one (like "restarting" it).
💡 By design, this feature only supports static notification types (success, error, warning, info) and not dynamic types (promise, promise-resolve, promise-reject).
If using Custom Components, it is possible to "detect" when a duplicate is pushed by watching the duplicateCount
property of the notification item (in your custom component setup function):
watch(
() => props.item.duplicateCount,
(newVal) => {
console.log(`Total duplicates: ${newVal}`)
}
)
For example, the above property could be used as component key to play/restart an animation everytime a duplicate of that notification is pushed (and its duration is updated).
Expose isStreamPaused
internal signal
Notivue now exposes a readonly reactive proxy of its internal isStreamPaused
signal, enabling consumers using Custom Components to create progress bars and advanced side-effects.
Check the docs website on how to implement a progress bar in your custom notification.
Wrapping up: <NotificationProgress />
drop-in component
Notivue's built-in Notifications now accept a default slot which can be used to add a new drop-in component named NotificationProgress
(and anything else you'd like to) which fully leverages the new APIs introduced above.
All you have to do is to import it and pass the notification item to the item
prop:
<script setup>
import { Notivue, Notification, NotificationProgress } from 'notivue'
import 'notivue/notification-progress.css'
</script>
<template>
<Notivue v-slot="item">
<Notification :item="item">
<NotificationProgress :item="item" />
</Notification>
</Notivue>
<!-- RouterView, etc. -->
</template>
💡 Please note that the CSS must also be imported either in
app.vue
or your app entry point.
v2.2.1
Release notes
This release brings few minor improvements to <Notifications />
and <NotivueSwipe />
.
Notifications
- Add
Notification
export as alias ofNotifications
in order to use it as the new default import mentioned in the documentation.
I have come to the conclusion that users may think they're importing a list, whereas they're actually importing a single notification. - Replace SVG spinner
<animate>
with pure CSS keyframes animation. - Add
--nv-y-align-has-title
theme variable. It is now possible to set a different vertical align that only applies to notifications with title. The variable is set tocenter
by default.
<Notification
:item="item"
:theme="{ ...lightTheme, '--nv-y-align-has-title': 'flex-start' }"
/>
In addition to that, it is now possible to conditionally style the notification elements by using the attribute data-notivue-has-title
,
.Notivue__notification[data-notivue-has-title='true'] {
/* */
}
NotivueSwipe
- Add a side-effect to move back the notification to its initial position if while dragging a new notification is pushed to the stream.
- Remove some unnecessary code related to state checks and timeouts clearing which was not removed in a previous release.
v2.2.0
Release notes
What's new
Disable Teleport
It is now possible to disable the built-in Teleport feature by passing false
to the teleportTo
config option:
const notivue = createNotivue({
teleportTo: false
})
Stream elements custom styles
<Notivue />
renders three elements with the following structure:
List container — ol
└── List items — li[]
└── Item container - div
└── Notification - slot
In order to orchestrate the stream according to your config, Notivue computes and adds some inline styles to the ol
, li
and div
elements. No classes nor other magic is involved, just those styles.
Since this release, it is now possible to define your own styles that take precedence over the default ones by passing a styles
object to the omonimous <Notivue />
prop:
<Notivue
:styles="{
list: {
position: 'relative'
height: '100%'
},
listItem: {},
itemContainer: {}
}"
v-slot="item"
>
<Notifications :item="item" />
</Notivue>
Both new features give you total control over the positioning, allowing, for example to render the stream relatevely to a specific container with a position other than fixed
.
What's improved
Refactor timeouts handling
The way Notivue handles pause and resume timeouts has been rewritten from scratch. The 60% of the involved code has been removed resulting in a much cleaner and clearer codebase.
The timeouts clearing logic has also been refactored. Compared to the previous releases, when a notification is about to be cleared, all the timeouts related to it are now cleared before triggering the leave animation and destroying the notification.
v2.1.1
v2.1.0
Release notes
The first minor release of Notivue v2, ships a new feature, fixes a NotivueSwipe bug and brings various improvements to the built-in notifications component.
What's new
useNotivue update
method
The object returned by useNotivue
now includes an update
method that can be used to update the configuration. Before this release it was only possible to update it by directly assigning a value to each returned ref:
Pre v2.1.0
const config = useNotivue()
config.postion.value = 'bottom-right'
config.enqueue.value = true
v2.1.0
const config = useNotivue()
config.update({
position: 'bottom-right',
enqueue: true,
})
New options will be merged to your initial configuration and so on. Alternatively, the same method also accepts a function that returns new options and exposes the current configuration as argument:
config.update((currConfig) => ({
enqueue: !currConfig.enqueue
}))
To update the configuration from outside the setup context, you can use the updateConfig
utility which has the same signature of the above-mentioned update
method:
import { updateConfig } from 'notivue'
What's fixed
NotivueSwipe - Fixed a bug where the computation of isPointerInside
was not performed correctly.
What's Improved
Notifications
- Add a tiny and light transition on
promise-resolve
andpromise-reject
icons appear using Vue Transition component. - Reduced the font-size from 1rem to 0.925rem.
- Disabled spinner animation when
prefers-reduced-motion
is set toreduce
- Lowered by little the saturation of the
slateTheme
foreground color. - Improved rendering performance by avoiding unnecessary computed properties to tracked.
Nuxt Module
- Add auto-imports for any theme and icon set.
Other
- Did a huge rename refactoring to the demo source files for better user inspection.
- Set the Vue compiler version to the latest 3.3.x release.
v2.0.0 - v2.0.1
Before wishing happy new year to everyone and going for a bit off until the beginning of January, I wanted to release Notivue v2.0.0
.
Release notes
This release unifies usage between Vite, Nuxt and Astro setups by bringing an isomorphic API that deprecates usePush
and exports push
from notivue
by finally allowing it to be called from anywhere no matter what framework is being used.
Upgrade guide
While usePush
has been deprecated, it is still exported from notivue
to facilitate the migration. For Nuxt setups, upgrading to v2.0.0 shouldn't break your code at all.
Unfortunately, for Vite-based setups an edit in both your main.js
and any file where you imported push
is required.
Vite
main.js
import { createNotivue } from 'notivue'
import { createApp } from 'vue'
import App from './App.vue'
+ const notivue = createNotivue(/* options */)
const app = createApp(App)
- export const push = createNotivue(app, /* options */)
+ app.use(notivue)
app.mount('#app')
In any of your files:
- import { push } from '@/main'
+ import { push } from 'notivue'
push.success('Hello from Notivue 2.0.0')
Nuxt
All you have to do is to remove this statement from anywhere in your code:
- const push = usePush()
push
is now auto-imported directly from notivue
and can be called from anywhere without worrying about the setup context.
What's new
notivue/astro
This package now exports Astro-dedicated versions of Notivue
and push
from notivue/astro
meant to connect the Notivue store to Astro client code using Custom Events.
This makes possible to push notifications from anywhere: script tags, React components, Vue components, you name it. Persistence of the notification stream across page navigation is also supported when using View Transitions.
Check the installation guide in the docs.
Promise Aliases
Promise-based notifications can now be pushed using the load
method alternatively to the promise
one and updated using success
and error
methods alternatively to resolve
and reject
. After using this package for a bit in my professional work, I realized that calling promise
, resolve
and reject
was a bit odd.
let notification = push.promise('Loading...')
notification.resolve('Done!')
// Same
let notification = push.load('Loading...')
notification.success('Done!')
let notification = push.promise('Loading...')
notification.reject('Error!')
// Same
let notification = push.load('Loading...')
notification.error('Error!')
What's fixed
- Improve repositioning performance by avoiding calling
triggerRef
when not necessary - Remove animation
enterClass
when completed. This prevents the enter animation to be played again when navigating between pages using Astro View Transitions.
What's changed
- Definitely remove deprecated
notivue
plugin. The compatibility fallback released in v1 is not anymore exported. - Definitely remove deprecated
useNotivueConfig
composable alias. - Remove
popIn
animation applied to built-in notifications icon.
v1.4.5
Release notes
- Import Nuxt composables from
#imports
instead of#app
. Thanks @danielroe - #32 - Fix
teleportTo
prop not working with HTML elements. Thanks @luxterful - #33