@linio/react-notifications
v0.2.1
Published
A notification system for React built with the Context API
Downloads
6
Readme
yarn add @linio/react-notifications
Features
- Load and store notifications to external services (defaults to
localStorage
) - Read/unread status
- Toast notifications
- Push (web) notifications
User Guide
Table of Contents
- Getting Started
- Creating a notification
- The notification object
- Accessing persisted notifications
- Marking a notification as read
- Writing your own
storageProvider
Getting Started
@linio/react-notifications
is built on top of React's Context API, therefore exposing a Provider
and Consumer
pair:
import { NotificationProvider, NotificationConsumer } from '@linio/react-notifications';
NotificationProvider
The NotificationProvider
"provides" the context of your notification system to your app. It should be added to the top of your component tree. If you are using other Provider
components from libraries such as redux or styled-components then this concept should be familiar to you.
// App.js
import { NotificationProvider } from '@linio/react-notifications';
class App extends Component {
// ...
render() {
return (
<NotificationProvider>
{/* App code */}
</NotificationProvider>
);
}
}
NotificationConsumer
The NotificationConsumer
allows you to "consume" the context of your notification system. It must render at any level beneath NotificationProvider
in the application tree.
// MyComponent.js
import { NotificationConsumer } from '@linio/react-notifications';
const MyComponent = () => (
<NotificationConsumer>
{context => {
/* where the magic happens! */
}}
</NotificationConsumer>
);
// App.js
import { NotificationProvider } from '@linio/react-notifications'
import MyComponent from './MyComponent'
class App extends Component {
// ...
render() {
return (
<NotificationProvider>
<MyComponent />
</NotificationProvider>
}
}
}
MyComponent
now has access to your notification system's context! 💥
Creating a notification
A notification can be created using the context.create
method.
context.create
<NotificationConsumer>
{({ create }) => {
const notification = create(options);
}}
</NotificationConsumer>
options
title
type
: string
required
: true
The title that will appear on the notification if rendered.
level
type
: 'SUCCESS', 'WARNING' or 'ERROR'
required
: true
Assigns a priority level to the notification. Also used internally for styling toast notifications.
body
type
: string or Function
required
: false
// text body
const notification = create({
title: 'Rich notification',
level: 'SUCCESS',
body: 'Im boring!'
});
// rich notification body
const notification = create({
title: 'Rich notification',
level: 'SUCCESS',
body: () => <p>Im rich!</p>
});
The body
property is used by both toast and push notifications, however, push notification can only receive a body
with the type string
. Toast notifications, on the other hand, can have a body
with the type string
or Function
, where the Function
should resemble a stateless functional component and returns some html
.
If a Function
is passed, @linio/react-notifications
will call that function and store the resulting html
for later use. This allows you to add more than just text. A link perhaps? 😏
requireInteraction
type
: boolean
required
: false
If set to true
, the notification will appear static on the screen (either as a toast or push notification) without dismissing itself after a set period of time (~5s).
The notification object
When you call the create
method, a notification object is returned, allowing you to take action in any way you see fit:
const notification = create(options);
notification.persist();
notification.toast();
notification.push();
.persist()
Stores the notification in context.notifications
.
.toast()
Renders a toast notification.
.push()
Creates a web notification by first checking the user's browser permissions. If denied, it will create a toast notification.
By default, the toast
and push
methods do not "persist" notifications. They will simply render them to the screen and then disappear quietly into the ether. However, you can chain the persist
method to opt-in to such functionality:
// render a toast notification and persist it for later access
notification
.toast()
.persist();
// render a push notification and persist it for later access
notification
.push()
.persist();
Accessing persisted notifications
Notifications that have been persisted with .persist
or that have been loaded from a storageProvider
are accessible via the context.notifications
array.
context.notifications
<NotificationConsumer>
{({ notifications }) => notifications.map(notification => { /* do stuff */})}
</NotificationConsumer>
// structure of a notification
{
id: string,
title: string,
level: 'SUCCESS' | 'WARNING' | 'ERROR',
timestamp: Date,
read: boolean,
options: {
body?: string | Function,
requireInteraction?: boolean
}
}
Marking a notification as read
When a notification is created, it will contain a read
property that defaults to false
. If you are persisting notifications and rendering them somewhere in your application, it is possible to expose read/unread functionality to your users through the context.markAsRead
method:
context.markAsRead
<NotificationConsumer>
{({ markAsRead }) => {
// ...
markAsRead(notification.id)
}}
</NotificationConsumer>
options
id
type
: string
required
: true
The id of the notification you wish to mark as read.
Writing your own storageProvider
By default, @linio/react-notifications
will load and store persisted notifications from localStorage
. This behavior requires no configuration on your part. You can, however, override this behavior to load and store persisted notifications from an external service of your own using a storageProvider
.
A storageProvider
is an object containing two methods, load
and store
. Each method is called at certain points of your application's lifecycle.
// storageProvider.js
export const load = () => notifications
export const store = data => {}
To link the storageProvider
to your notification system, pass the functions as load
and store
props to NotificationProvider
.
// App.js
import { NotificationProvider } from '@linio/react-notifications';
import { load, store } from './storageProvider';
class App extends Component {
// ...
render() {
return (
<NotificationProvider load={load} store={store}>
{/* App code */}
</NotificationProvider>
);
}
}
Alternatively, if your app supports object rest/spread, you can use this nifty syntactic sugar:
// App.js
import { NotificationProvider } from '@linio/react-notifications';
import * as storageProvider from './storageProvider';
class App extends Component {
// ...
render() {
return (
<NotificationProvider {...storageProvider}>
{/* App code */}
</NotificationProvider>
);
}
}
storageProvider.load
Should return an array of persisted notifications.
// storageProvider.js
const load = () => { /* returns an array of notifications */ }
When is storageProvider.load
called?
The storageProvider.load
method is called when NotificationProvider
mounts, and it will initialize your notification system's context with the returned array.
storageProvider.store
Accepts a single notification or an array of notifications.
// storageProvider.js
const store = data => { /* data === notification || Array<notification>*/}
When is storageProvider.store
called?
Each time a notification is persisted using the .persist()
method, @linio/react-notifications
will check to see if you have provided a custom storageProvider
with a store
method on it. If you have, this method will receive the newly persisted notification.
Contributing
git clone [email protected]:LinioIT/react-notifications.git
yarn test
Tooling
@linio/react-notifications
uses the following tools internally: