README
Vanilla Toaster
Simple toaster in vanilla JavaScript for modern browsers.
Why
- 🦄 Simple and elegant
- âš¡ Lightweight, 2kb gzipped CSS + JS
- 😎 Modern
- 📦 Zero Dependencies
- 🔌 Compatible with all modern UI frameworks and libraries
- 🎨 Easily customizable with themes and custom CSS
Demo
Check out the demo page. You can use it to play around with different kinds of toasts.
Browser Support
Latest and the greatest.
Usage
- Install by
yarn add @ajmey/toaster
, ornpm i @ajmey/toaster --save
. - Load the toaster:
import toaster from "@ajmey/toaster"
. - Call any toast, eg
toaster.success("Done!", { dismiss: 1500 })
.
Using the default export above, the CSS & JS are loaded automatically. This is the fastest way to get started, but the final bundle is a little larger. Ideally, you should load the CSS and the JS separately:
Load CSS
<link rel="stylesheet" href="node_modules/@ajmey/toaster/themes/theme-default.min.css">
or if you are using a bundler like Webpack:
import "@ajmey/toaster/themes/theme-default.min.css";
Then, use in JS:
JS
import { useToaster } from "@ajmey/toaster/toaster";
/* factory function `useToaster` does not inject CSS */
const toaster = useToaster({animation: "appear", theme: "default"});
toaster.success();
Please check out the module formats and initialization sections for more details.
API
toaster
The toaster
object has the following methods for invoking a toast:
success
failure
info
warning
The above methods all have the following signature:
[toastType](message?: string, options?: object) -> Promise<DOM Node>
message
:string
the message to showoptions
(optional):object
plain object defining the options:options.dismiss
:number
auto dismiss a toast afterdismiss
milliseconds. If the value is falsy, auto-dismiss is disabled. All toasts, except the Success toast, are dismissed by default after1500
ms.options.title
:string
title to be used for the toast.options.theme
:string
you can override the theme used in initializationoptions.animation
:string
you can also override the animation used initially
Return Value: each method will return a promise
that resolves to the wrapper DOM element holding the toaster. The wrapper node is useful if you use set dismiss
to false
because you will have access to the wrapper node at that point.
Examples:
toaster.failure("This is the message body". { title: "Error!", dismiss: false, animation: "appear", theme: "dark"});
toaster.success("Todo item was created!");
toaster.info();
toaster.failure("Something went wrong", { dismiss: false})
.then(wrapperNode => console.log(wrapperNode));
clear()
:
If you want to clear the active toast, simply call toaster.clear()
. Returns a promise when the toasts are removed. Resolves with the number of toasts removed.
Example
toaster.clear().then(count => console.log("cleared toasters: ", count));
on(eventName, callback)
: can be used to add event handlers:
eventName
:string
the event name, possible values are:beforeLoad
,loaded
,beforeCleared
,cleared
.callback
:function
the event handler callback to be called
Examples:
import toaster from "@ajmey/toaster";
toaster.on("beforeLoad", () => {
console.log("before loaded");
});
toaster.on("loaded", () => {
console.log("toaster loaded.");
});
toaster.on("beforeClear", () => {
console.log("beforeClear");
});
toaster.on("cleared", () => {
console.log("toast cleared.");
});
Initialization
There are two ways that you can use a toaster object:
useToaster
factory function is available in@ajmey/toaster/toaster
. The factory function does not inject any css by default unless aninjectStyles
function is given,useToaster(options?: object, injectStyles?: function)
:options.theme
:string
, theme name, egdefault
,dark
, etc. If no value is given,default
is used.options.animation
:string
, defining the name of the animation. Defaults toappear
if no value is set.
The
injectStyles
function can be passed in order to inject custom css to the page. Please seegh-pages/index.dev3.html
for usage example.Basic example:
import { useToaster } from "@ajmey/toaster/toaster"; const toaster = useToaster({ theme: "dark", animation: "appear" }); toaster.success("hello world!");
Using the default import
The default export on
@ajmey/toaster
is atoaster
object with all default values. If you use this method, the CSS is also automatically injected to the page and the toaster instance is already initialized:Example:
JS
import toaster from "@ajmey/toaster"; toaster.success("Hello!");
Themes
You can override the colors of the toaster by including your own css after the toaster's. For example, if you want to create a light
theme, you can do:
CSS
.ajmtoaster.theme-light,
.ajmtoaster.theme-default {
--ajmt-white: #fff;
--ajmt-success: green;
--ajmt-failure: red;
--ajmt-warning: yellow;
--ajmt-info: blue;
/* transition properties */
--ajmt-duration: 400ms;
--ajmt-easing: ease-in-out;
}
In the example above, we are also including .theme-default
to account for all possible ways that the module could be loaded.
Animations
By default, toaster uses the appear
animation. You can create new animations using the following selectors:
.ajmtoaster.--animation-slide-down,
.ajmtoaster.--animation-slide-down.--active {
transition: transform var(--ajmt-duration) var(--ajmt-easing) 0ms,
opacity var(--ajmt-duration) var(--ajmt-easing) 50ms;
}
.ajmtoaster.--animation-slide-down {
opacity: 0;
transform: translateY(-20px);
}
.ajmtoaster.--animation-slide-down.--active {
opacity: 1;
transform: translateY(0);
}
In the example above, we create a new animation called slide-down
. Once the CSS is defined, you can pass animation
as an option to useToaster
:
import { useToaster } from "@ajmey/toaster/toaster";
const toaster = useToaster({ animation: "slide-down" });
Overriding CSS
It's very easy to override every CSS rule, since all of them use a single class name with one or two modifiers max:
.ajmtoaster
: the main wrapper around the whole toaster..ajmtoaster__inner
: inner content of the toaster..ajmtoaster__inner.--success
: success modifier.ajmtoaster__inner.--failure
: failure modifier.ajmtoaster__inner.--warning
: warning modifier.ajmtoaster__inner.--info
: info modifier
.ajmtoaster__title
: the title for the toaster..ajmtoaster__message
: toaster message..ajmtoaster__dismiss
: the button to dismiss the toaster.
Every single class above have a theme modifier as well, in the form of .[classname].[theme]
. For example:
.ajmtoaster.theme-dark
.ajmtoaster__inner.theme-dark
.ajmtoaster__inner.--success.theme-dark
- etc
Modules
This package is available both in ES and UMD formats:
ESM
import toaster from "@ajmey/toaster"; // default import
import {useToaster, injectStyles} from "@ajmey/toaster/toaster";
All the ESM modules are importable from the root @ajmey/toaster/<module>
:
- index.js
- toaster.js
- themes.js
UDM
All the UMD formats are available in the node_modules/@ajmey/toaster/umd
. When loaded in the global context, window.ajmtoaster
is available. For example:
<script src="node_modules/@ajmey/toaster/umd/index.js"></script>
<script>
console.log(window.ajmtoaster.themes.baseCss.length);
window.toaster = window.ajmtoaster.default;
window.toaster2 = window.ajmtoaster.useToaster({ animation: "appear", theme: "dark"})
window.toaster2.failure("Something went wrong.");
</script>
Bundle Size
minified + gzipped
If using JS/CSS separately, the smallest total size will be: 1.4K + 772B = 2.172 kb:
- esm/toaster.min.js.gz: 1.4K
- themes/theme-default.min.css.gz: 772B
Development
- Make sure to install the latest LTS version of Node:
nvm install --lts
. - Install yarn with
npm i -g yarn
. - Install dependencies with
yarn install
. - Run
yarn dev
to start rollup and css watch. - Update code in the
src/
folder. - Run the examples (gh-pages) locally:
yarn serverd
- Open
http://localhost:8080/gh-pages/index.dev*.html
to check the functionality. - To run the e2e tests in watch mode, run
yarn server && yarn e2ew
. TestCafe will start testing whats served at 8080.
Maintainer
To publish a new version:
yarn prep
and git add and commit all.npm version patch|minor|major
&&yarn build
&&npm publish --access=public