Package Exports
- react-toastsnack
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-toastsnack) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
react-toastsnack
An unopinionated notification queue for React
Installation
Using npm:
$ npm install react-toastsnack
Using yarn:
$ yarn add react-toastsnack
Then with a module bundler like webpack, use as you would anything else:
// Using ES6 Modules
import { useToastSnack } from 'react-toastsnack';
// using CommonJS modules
const useToastSnack = require('react-toastsnack').useToastSnack;
Usage
At the top-level of your application, import the ReactToastSnackProvider
module.
// AppContext.js
import React from 'react';
import { ReactToastSnackProvider } from 'react-toastsnack';
function AppContext() {
return (
<ReactToastSnackProvider>
<App />
</ReactToastSnackProvider>
);
}
The provider provides (ahem) you with a set of parameters:
renderer
requiredmethods
optionaldismiss
optionalinitial
optionalheight
optionaloffset
optionaldelay
optionalmax
optional
renderer
This prop is required, and is the component used to render a single notification.react-toastsnack
has no opinion on how you choose to render it.
Props
provided to the renderer:
toastSnack
_id
_open
_offset
_ And any other props passed upon creation of the notification.onUpdate
onExited
onClose
For example, let's say we're using the material-ui component library.
The renderer
may look something like this:
// AppContext.js
import React from 'react';
import { ReactToastSnackProvider } from "react-toastsnack";
import Snackbar from "@material-ui/core/Snackbar";
function AppContext() {
return (
<ReactToastSnackProvider renderer={ToastSnack}>
<App />
</ReactToastSnackProvider>
)
}
const ToastSnack = React.memo(props => {
const { onUpdate, onExited, onClose, toastSnack } = props;
const {
id,
open,
offset
// Any other props are controlled by you.
style,
message,
contentProps,
autoHideDuration,
...other
} = toastSnack;
// If the snack height isn't the same as the default height
// which we provided to ReactToastSnackProvider, we may want to update it
const ref = useRef(null);
useLayoutEffect(() => {
const height = ref.current?.clientHeight;
if (height && snackProps.height !== height) {
onUpdate({ id, height });
}
}, [id, onUpdate, snackProps.height]);
const handleClose = React.useCallback((event,reason) => {
if (reason === "clickaway") return;
onClose(id);
}, [id, onClose]);
const handleExited = React.useCallback((event) => {
onExited(id);
}, [id, onExited]);
return (
<RootRef rootRef={ref}>
<Snackbar
style={style}
onClose={handleClose}
onExited={handleExited}
autoHideDuration={autoHideDuration}
{...other}
>
<SnackbarContent
message={message}
{...contentProps}
/>
</Snackbar>
</RootRef>
)
});
methods
The methods
prop allows you to pass an object containing functions, which generate custom methods.
Any functions you provide here, can be accessed through the useToastSnack
/withToastSnack
api.
For example, I want to implement a notification centered around a promise.
// AppContext.js
import React from 'react';
import { ReactToastSnackProvider } from "react-toastsnack";
function AppContext() {
const methods = React.useMemo(() => {
// onCreate and onUpdate is passed, so we can create a custom flow.
promise: (onCreate, onUpdate) => {
return ({promise, ...other}) => {
// Create a new notification and save the id to a variable
// We've set the duration to null, in order to persist
// the notification until the promise is resolved or rejected
const id = onCreate({
...other,
duration: null,
color: "colorLoading",
message: "Please wait for something",
});
promise
// If the promise is resolved,
// change the color to `colorSuccess`, update the message
// and change the duration to 1000
.then(() => {
onUpdate({
...other,
id,
duration: 1000,
color: "colorSuccess",
message: "You bought 3 puppies!",
});
})
// If the promise is rejected, inform the user
// by changing the color to colorError and updating the message
// The duration is set to 5000
.catch(() => {
onUpdate({
id,
duration: 5000,
color: "colorError",
message: "An error occurred!",
})
})
}
}
})
return (
<ReactToastSnackProvider methods={methods} renderer={...}>
<App />
</ReactToastSnackProvider>
)
}
To use the custom promise
method, just import useToastSnack
and call it like any other internal method.
// components/Elsewhere.js
import { useToastSnack } from 'react-toastsnack';
function Elsewhere() {
const toastSnack = useToastSnack();
// When the button is clicked, create a new promise
// to display a loading notification, which will change whenever the request responds
return (
<button
onClick={() => {
toastSnack.promise({
promise: fetch(puppies_url, { method: 'POST' }),
});
}}
>
Click here to buy puppies
</button>
);
}
Note that the duration
, color
and message
variables in this example are completely arbitrary.
You have full control over any variables which are not id
, open
or offset
.
dismiss
?boolean
: Whether or not we should dismiss active notifications to display new ones, if the max
count has been reached.
Default: false
initial
?Array<ToastSnack>
: A list of initial notifications.
Default: []
height
?number
: The default assumed height for calculating offsets. This can be overwritten by using the onUpdate
function.
Default: 48
offset
?number
: The offset and distance between notifications.
Default: 8
delay
?number
: The transition delay; How long to wait between a dismissal and queueing the next notification.
Default: 400
max
?number
: The maximum number of concurrent notifications.
Default: null
Credits
react-toastsnack is built and maintained by babangsund.
@blog.
@github.
@twitter.