@mikebeas/notify v1.1.3
Notify
Notify provides an easy way to present nice notifications in your web app. That's all it does.
Usage
Add a <Notification />
to the highest feasible component in your tree. This should probably be your App.js if you're using create-react-app
, for example. This component accepts 3 props: onClick
, showAtTop
(starting in version 1.1.0), and customClass
.
You only need one of these <Notification />
components in your application. It provides a container that will render all of your notifications.
There are also two methods you'll want to use. The first is notify()
, the purpose of which I hope is obvious, and dismissNotification()
which, hopefully, is just as obvious.
Here's an example.
Import React from 'react'
import Notification { notify, dismissNotification } from '@mikebeas/notify'
const App = () => {
return(
<>
<Notifiation
onClick={dismissNotification}
customClass="my-very-special-class"
/>
<HeaderMenu />
<OtherLessImportantComponent />
<SomethingElse />
</>
)
}
Passing a function to the onClick
prop will run the function with the click event as input. Nothing special.
You'll notice that in this example the click handler is dismissNotification
. That does not have to be the case, but you should consider using it, either as the default handler or as part of a custom handler (more on that in a minute).
When sending a notification, you need to specify a message and you have the option of specifying a few other options along with it using notify()
. The message to display should be passed as a string in the first argument. Optionally, you can pass an object containing any of the following options to apply them to a specific notification. This means that you can have separate colors for different uses, such as red for errors and blue for notifications.
The available options are:
backgroundColor
- Changes the banner color
- String - Accepts any CSS-friendly color
- Default: red
textColor
- Changes text color
- String - Accepts any CSS-friendly color
- Default: white
hangTime
- Time in seconds to automatically dismiss banner
- Number
- Default: 5
hideShadow
- Hides the banner's drop shadow
- Useful for design purposes, but really only exists as part of an old Safari animation workaround
- Boolean
- Default: false
An example:
const USER_ID_MISSING = 'Your user ID is not setup. Please visit Settings to enter your ID.'
const ERROR_SETTINGS = {
backgroundColor: 'rgb(209, 0, 0)',
textColor: 'whitesmoke',
hangTime: 10
}
if (!userID) {
notify(USER_ID_MISSING, ERROR_SETTINGS)
} else {
...
}
In the situation shown above, you may want to allow the user to click the banner to open the Settings page immediately. To do this (and I'm sorry about how hacky this is, with the innerText and all), you can add a custom click handler to your <Notification />
that checks what notification is being displayed and handles each click accordingly.
function handleNotificationClick(e) {
let notificationMessage = e.target.innerText
switch (notificationMessage) {
case USER_ID_MISSING:
openSettings();
dismissNotification();
break;
default:
dismissNotification();
break;
}
}
const App = () => {
return(
<>
<Notifiation onClick={handleNotificationClick} />
<OtherComponents />
</>
)
}
More Styling
Aside from the options specified above, there are other ways to customize your notifications. You can pass in a customClass
prop that contains one or more custom CSS classes to apply, then customize those to your heart's content. Note that these will be applied to all notifications and should be used to setup your global style for your application where the per-notification options will not suffice (border radius, for example). I guess if you wanted to be fancy you could even make customClass
conditional. Up to you.
If you want to tweak the animations, you can do that. Just override the .mikebeas_notify
class in your application's CSS. In theory you could also override mikebeas_notification-container
and mikebeas_notification
to change the placement of the banners and the actual banners themselves, respectively (although, again, customClass
is probably your best bet for that last one).
If you prefer notifications to show at the top of the page rather than the bottom, pass in a prop called showAtTop
with a boolean value of true
.
If you tweak the animations, be aware that there are some figures hardcoded into notify()
which assumes a 500ms dismiss time. This is used when rendering a second notification while another one is active. The script will see the second one coming in, dismiss the first one, wait just long enough for it to get off screen, re-render with the updated message and options, and then slide the new notification in. It's recycling the same div
every time. If your tweaked animation is slower than 500ms to dismiss from the user's screen, they may see this transition take place. It doesn't look horrible but it does look a little weird. But you can do it if you want!
Known Issues
Sometimes the notifications can get to dismissing a little too quickly if you post a bunch of them really quickly, which causes all future notifications to dismiss early until the page is refreshed. I guess just don't post a whole bunch of notificiations back-to-back-to-back-to-back? Sorry.
That Old Safari Workaround
This is no longer necessary but might just be fun for you to know if you're curious. The reason hideShadow
exists is that Safari used to have an issue with the placement of the notification when animating the first banner onto the page. Rather than center the banner on the page, then animate it in, it would animate in slightly off-center, then jump it to the center of the page. This didn't happen in Chrome.
The workaround was to simply trigger a notification with no content and a transparent RGBA background and text color. This, of course, left the banner's shadow visible. So I added the option to hide the shadow specifically for use in that initial Safari notifiication so that it could happen invisibly and the banner would be centered correctly for future use.
That issue was resolved with the addition of the container div that you'll see if you examine the page source (in Chrome having only the notification div worked fine so I never bothered adding the container div until I noticed the Safari problem). No workaround is necessary now and everything should work as described above in both browsers. No other browsers have been tested at this time.