├── .gitignore ├── .npmrc ├── .travis.yml ├── README.md ├── cypress.json ├── cypress ├── fixtures │ └── example.json ├── integration │ ├── page.html │ └── tiny-toast-spec.js └── support │ ├── commands.js │ └── defaults.js ├── deploy.json ├── dist ├── index.html └── tiny-toast.js ├── images └── cypress-test.png ├── index.js ├── package.json ├── tiny-toast.png └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .grunt/ 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=http://registry.npmjs.org/ 2 | save-exact=true 3 | progress=false 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '6' 10 | before_script: 11 | - npm prune 12 | - npm install -g cypress-cli 13 | script: 14 | - npm test 15 | - cypress ci 16 | after_success: 17 | - npm run semantic-release 18 | branches: 19 | except: 20 | - "/^v\\d+\\.\\d+\\.\\d+$/" 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tiny-toast 2 | > Tiny library for JavaScript only message popups 3 | 4 | [![NPM][tiny-toast-icon] ][tiny-toast-url] 5 | 6 | [![Build status][tiny-toast-ci-image] ][tiny-toast-ci-url] 7 | [![semantic-release][semantic-image] ][semantic-url] 8 | [](https://github.com/bahmutov/manpm) 9 | 10 | [demo](http://glebbahmutov.com/tiny-toast/) 11 | 12 |  13 | 14 | ## Install and use 15 | 16 | `npm install tiny-toast` 17 | 18 | Include `dist/tiny-toast.js` script 19 | 20 | ```html 21 | 22 | 29 | ``` 30 | 31 | You can also use this library via [RawGit CDN](https://rawgit.com/) by grabbing the 32 | CDN path to the `https://github.com/bahmutov/tiny-toast/blob/master/dist/tiny-toast.js` or 33 | specific tag. 34 | 35 | ## Custom style 36 | 37 | You can adjust the element's CSS style by providing your own rules. Just 38 | mark them "important". 39 | 40 | ``` 41 | 47 | ``` 48 | 49 | ### Small print 50 | 51 | Author: Gleb Bahmutov © 2015 52 | 53 | * [@bahmutov](https://twitter.com/bahmutov) 54 | * [glebbahmutov.com](http://glebbahmutov.com) 55 | * [blog](http://glebbahmutov.com/blog/) 56 | 57 | License: MIT - do anything with the code, but don't blame me if it does not work. 58 | 59 | Spread the word: tweet, star on github, etc. 60 | 61 | Support: if you find any problems with this module, email / tweet / 62 | [open issue](https://github.com/bahmutov/tiny-toast/issues) on Github 63 | 64 | ## MIT License 65 | 66 | Copyright (c) 2015 Gleb Bahmutov 67 | 68 | Permission is hereby granted, free of charge, to any person 69 | obtaining a copy of this software and associated documentation 70 | files (the "Software"), to deal in the Software without 71 | restriction, including without limitation the rights to use, 72 | copy, modify, merge, publish, distribute, sublicense, and/or sell 73 | copies of the Software, and to permit persons to whom the 74 | Software is furnished to do so, subject to the following 75 | conditions: 76 | 77 | The above copyright notice and this permission notice shall be 78 | included in all copies or substantial portions of the Software. 79 | 80 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 81 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 82 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 83 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 84 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 85 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 86 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 87 | OTHER DEALINGS IN THE SOFTWARE. 88 | 89 | [tiny-toast-icon]: https://nodei.co/npm/tiny-toast.svg?downloads=true 90 | [tiny-toast-url]: https://npmjs.org/package/tiny-toast 91 | [tiny-toast-ci-image]: https://travis-ci.org/bahmutov/tiny-toast.svg?branch=master 92 | [tiny-toast-ci-url]: https://travis-ci.org/bahmutov/tiny-toast 93 | [semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg 94 | [semantic-url]: https://github.com/semantic-release/semantic-release 95 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectId": "c7215ca8-b515-4281-8178-ed21402c9a34" 3 | } 4 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } -------------------------------------------------------------------------------- /cypress/integration/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |19 | Tiny JavaScript only popup messages. 20 |
npm install --save tiny-toast22 |
tinyToast.show('Hello from tiny toast') 24 | // timeout (ms) is optional 25 | tinyToast.hide(2000)26 | 27 |
Repo bahmutov/tiny-toast
28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /dist/tiny-toast.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["tinyToast"] = factory(); 8 | else 9 | root["tinyToast"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | 39 | 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = ""; 48 | 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ function(module, exports) { 56 | 57 | 'use strict' 58 | 59 | var tinyToast 60 | 61 | function createCssStyleSheet () { 62 | // code taken from 63 | // https://davidwalsh.name/add-rules-stylesheets 64 | const style = document.createElement('style') 65 | // WebKit hack :( 66 | // style.appendChild(document.createTextNode('')) 67 | document.head.appendChild(style) 68 | return style.sheet 69 | } 70 | 71 | function insertStyle (className, sheet, style) { 72 | // insert a rule for each style property 73 | Object.keys(style).forEach((key) => { 74 | const value = style[key] 75 | sheet.insertRule(`.${className} { ${key}: ${value} }`, 0) 76 | }) 77 | } 78 | 79 | function createTinyToastStyle () { 80 | const className = 'tinyToast' 81 | const style = { 82 | color: '#333', 83 | position: 'fixed', 84 | bottom: '0em', 85 | right: '1em', 86 | 'background-color': '#7FFFD4', 87 | 'border-radius': '5px', 88 | 'border-width': '1px', 89 | 'border-color': '#73E1BC', 90 | 'border-style': 'solid', 91 | padding: '1em 2em', 92 | 'z-index': 1000 93 | } 94 | 95 | const sheet = createCssStyleSheet() 96 | insertStyle(className, sheet, style) 97 | return className 98 | } 99 | 100 | function createDom () { 101 | if (tinyToast) { 102 | return tinyToast 103 | } 104 | 105 | const className = createTinyToastStyle() 106 | 107 | tinyToast = document.createElement('h3') 108 | tinyToast.classList.add(className) 109 | document.body.appendChild(tinyToast) 110 | return tinyToast 111 | } 112 | 113 | function createMessage (text) { 114 | createDom().textContent = text 115 | } 116 | 117 | function closeMessage () { 118 | if (tinyToast) { 119 | document.body.removeChild(tinyToast) 120 | tinyToast = null 121 | } 122 | } 123 | 124 | function maybeDefer (fn, timeoutMs) { 125 | if (timeoutMs) { 126 | setTimeout(fn, timeoutMs) 127 | } else { 128 | fn() 129 | } 130 | } 131 | 132 | function hide (timeoutMs) { 133 | maybeDefer(closeMessage, timeoutMs) 134 | } 135 | 136 | var tinyToastApi = { 137 | show: function show (text) { 138 | createMessage(text) 139 | return tinyToastApi 140 | }, 141 | hide: hide 142 | } 143 | 144 | module.exports = tinyToastApi 145 | 146 | 147 | /***/ } 148 | /******/ ]) 149 | }); 150 | ; -------------------------------------------------------------------------------- /images/cypress-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bahmutov/tiny-toast/8ab63c4ab8ca85aea91a0910a3af92da8e82e090/images/cypress-test.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var tinyToast 4 | 5 | function createCssStyleSheet () { 6 | // code taken from 7 | // https://davidwalsh.name/add-rules-stylesheets 8 | const style = document.createElement('style') 9 | // WebKit hack :( 10 | // style.appendChild(document.createTextNode('')) 11 | document.head.appendChild(style) 12 | return style.sheet 13 | } 14 | 15 | function insertStyle (className, sheet, style) { 16 | // insert a rule for each style property 17 | Object.keys(style).forEach((key) => { 18 | const value = style[key] 19 | sheet.insertRule(`.${className} { ${key}: ${value} }`, 0) 20 | }) 21 | } 22 | 23 | function createTinyToastStyle () { 24 | const className = 'tinyToast' 25 | const style = { 26 | color: '#333', 27 | position: 'fixed', 28 | bottom: '0em', 29 | right: '1em', 30 | 'background-color': '#7FFFD4', 31 | 'border-radius': '5px', 32 | 'border-width': '1px', 33 | 'border-color': '#73E1BC', 34 | 'border-style': 'solid', 35 | padding: '1em 2em', 36 | 'z-index': 1000 37 | } 38 | 39 | const sheet = createCssStyleSheet() 40 | insertStyle(className, sheet, style) 41 | return className 42 | } 43 | 44 | function createDom () { 45 | if (tinyToast) { 46 | return tinyToast 47 | } 48 | 49 | const className = createTinyToastStyle() 50 | 51 | tinyToast = document.createElement('h3') 52 | tinyToast.classList.add(className) 53 | document.body.appendChild(tinyToast) 54 | return tinyToast 55 | } 56 | 57 | function createMessage (text) { 58 | createDom().textContent = text 59 | } 60 | 61 | function closeMessage () { 62 | if (tinyToast) { 63 | document.body.removeChild(tinyToast) 64 | tinyToast = null 65 | } 66 | } 67 | 68 | function maybeDefer (fn, timeoutMs) { 69 | if (timeoutMs) { 70 | setTimeout(fn, timeoutMs) 71 | } else { 72 | fn() 73 | } 74 | } 75 | 76 | function hide (timeoutMs) { 77 | maybeDefer(closeMessage, timeoutMs) 78 | } 79 | 80 | var tinyToastApi = { 81 | show: function show (text) { 82 | createMessage(text) 83 | return tinyToastApi 84 | }, 85 | hide: hide 86 | } 87 | 88 | module.exports = tinyToastApi 89 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tiny-toast", 3 | "description": "Tiny library for JavaScript only message popups", 4 | "version": "0.0.0-semantic-release", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "npm run lint", 8 | "lint": "standard --verbose --fix *.js cypress/integration/*.js", 9 | "commit": "commit-wizard", 10 | "build": "webpack --verbose", 11 | "semantic-release": "semantic-release pre && npm publish && semantic-release post", 12 | "deploy": "grunty grunt-gh-pages gh-pages deploy.json", 13 | "size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";", 14 | "issues": "git-issues" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/bahmutov/tiny-toast.git" 19 | }, 20 | "files": [ 21 | "index.js", 22 | "dist" 23 | ], 24 | "keywords": [ 25 | "message", 26 | "popup", 27 | "alert", 28 | "javascript", 29 | "micro", 30 | "tiny", 31 | "ui" 32 | ], 33 | "author": "Gleb Bahmutov