├── .babelrc ├── .gitignore ├── .npmignore ├── CNAME ├── LICENSE ├── README.md ├── gulpfile.js ├── package.json └── src ├── jade └── index.jade ├── js └── biu.js └── styl └── biu.styl /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015-rollup"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /demo 2 | /dist 3 | 4 | # Logs 5 | logs 6 | *.log 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 30 | node_modules 31 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /demo -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | biu.js.org 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 四月橘林 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # biu [![NPM version](https://img.shields.io/npm/v/biu.js.svg?style=flat-square)](https://npmjs.com/package/biu.js) [![JS.ORG](https://img.shields.io/badge/js.org-biu-ffb400.svg?style=flat-square)](http://biu.js.org) 2 | 3 | An alert replacement (JS + CSS = 3KB) 4 | 5 | ## Install 6 | 7 | ```bash 8 | $ npm install biu.js 9 | ``` 10 | 11 | ## Usage and Demo 12 | 13 | Visit [Biu](http://biu.js.org) 14 | 15 | ## Browser support 16 | 17 | IE 9 and above should be supported, and last 2 versions of other modern browsers are supported. 18 | 19 | ## Directory tree 20 | 21 | This `dist` is excluded in git but included in npm package. 22 | 23 | ```bash 24 | dist 25 | ├── biu.css 26 | ├── biu.js 27 | ├── biu.cjs.js 28 | ├── biu.min.js 29 | └── biu.min.js.map 30 | ``` 31 | 32 | ## Related 33 | 34 | [corner-notie](https://github.com/egoist/corner-notie) - A light-weight toastr notifications utility for the web. 35 | 36 | ## Development 37 | 38 | use `npm run build` to build or `npm run dev` to build and watch. 39 | 40 | ## License 41 | 42 | [MIT](/LICENSE) 43 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var 2 | gulp = require('gulp'), 3 | jade = require('gulp-jade'), 4 | stylus = require('gulp-stylus'), 5 | sourcemaps = require('gulp-sourcemaps'), 6 | serve = require('gulp-serve'), 7 | babel = require('rollup-plugin-babel'), 8 | postcss = require('gulp-postcss'), 9 | autoprefixer = require('autoprefixer'), 10 | cssnano = require('cssnano'), 11 | uglify = require('gulp-uglify'), 12 | rename = require('gulp-rename'), 13 | rollup = require('gulp-rollup') 14 | 15 | var rollupConfig = { 16 | plugins: [ 17 | babel() 18 | ], 19 | format: 'umd', 20 | moduleName: 'biu' 21 | } 22 | 23 | gulp.task('serve', serve({ 24 | root: ['./demo'], 25 | port: 3000 26 | })); 27 | 28 | gulp.task('js', function() { 29 | gulp.src('./src/js/biu.js') 30 | .pipe(rollup(rollupConfig)) 31 | .pipe(gulp.dest('./dist')) 32 | .pipe(gulp.dest('./demo')) 33 | }) 34 | 35 | gulp.task('js:cjs', function() { 36 | var config = Object.assign({}, rollupConfig, { 37 | format: 'cjs' 38 | }) 39 | gulp.src('./src/js/biu.js') 40 | .pipe(rollup(config)) 41 | .pipe(rename('biu.cjs.js')) 42 | .pipe(gulp.dest('./dist')) 43 | .pipe(gulp.dest('./demo')) 44 | }) 45 | 46 | gulp.task('js:min', function() { 47 | var config = Object.assign({}, rollupConfig, { 48 | sourceMap: true 49 | }) 50 | gulp.src('./src/js/biu.js') 51 | .pipe(sourcemaps.init()) 52 | .pipe(rollup(config)) 53 | .pipe(uglify()) 54 | .pipe(rename({suffix: '.min'})) 55 | .pipe(sourcemaps.write('.')) 56 | .pipe(gulp.dest('./dist')) 57 | .pipe(gulp.dest('./demo')) 58 | }) 59 | 60 | gulp.task('html', function() { 61 | gulp.src('./src/jade/index.jade') 62 | .pipe(jade({ 63 | locals: { 64 | buildTime: new Date().getTime() 65 | } 66 | })) 67 | .pipe(gulp.dest('./demo')) 68 | }) 69 | 70 | gulp.task('css', function() { 71 | gulp.src('./src/styl/biu.styl') 72 | .pipe(stylus()) 73 | .pipe(postcss([ 74 | autoprefixer({ 75 | browsers: ['ie > 8', 'last 2 versions'] 76 | }), 77 | cssnano() 78 | ])) 79 | .pipe(gulp.dest('./dist')) 80 | .pipe(gulp.dest('./demo')) 81 | }) 82 | 83 | gulp.task('watch', function() { 84 | gulp.watch('./src/jade/index.jade', ['html']) 85 | gulp.watch('./src/styl/biu.styl', ['css']) 86 | gulp.watch('./src/js/biu.js', ['js', 'js:min']) 87 | }) 88 | 89 | gulp.task('build', ['js', 'js:min', 'js:cjs', 'css', 'html']) 90 | 91 | gulp.task('default', ['build', 'watch', 'serve']) 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "biu.js", 3 | "version": "1.2.0", 4 | "description": "an alert replacement", 5 | "main": "./dist/biu.cjs.js", 6 | "scripts": { 7 | "test": "xo src/js/*.js", 8 | "dev": "gulp", 9 | "build": "gulp build", 10 | "demo": "npm run build && cp CNAME demo/ && gh-pages -d demo" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/egoist/biu.git" 15 | }, 16 | "keywords": [ 17 | "alert", 18 | "notification", 19 | "notice", 20 | "warn", 21 | "utility" 22 | ], 23 | "author": "EGOIST <0x142857@gmail.com>", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/egoist/biu/issues" 27 | }, 28 | "files": [ 29 | "dist" 30 | ], 31 | "homepage": "https://github.com/egoist/biu#readme", 32 | "devDependencies": { 33 | "autoprefixer": "^6.3.6", 34 | "babel-preset-es2015-rollup": "^1.1.1", 35 | "cssnano": "^3.5.2", 36 | "gulp": "^3.9.0", 37 | "gulp-jade": "^1.0.1", 38 | "gulp-postcss": "^6.1.1", 39 | "gulp-rename": "^1.2.2", 40 | "gulp-rollup": "^1.9.0", 41 | "gulp-serve": "^1.0.0", 42 | "gulp-sourcemaps": "^1.5.2", 43 | "gulp-stylus": "^2.0.5", 44 | "gulp-uglify": "^1.5.3", 45 | "marked": "^0.3.3", 46 | "rollup-plugin-babel": "^2.4.0", 47 | "xo": "^0.15.1" 48 | }, 49 | "xo": { 50 | "space": 2, 51 | "semicolon": false, 52 | "envs": [ 53 | "browser" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/jade/index.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | meta(charset="utf-8") 5 | meta(name="viewport",content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no") 6 | title Biu 7 | link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.2/css/font-awesome.min.css") 8 | link(rel="stylesheet", href="./biu.css?t=#{buildTime}") 9 | link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism.min.css") 10 | style. 11 | body { 12 | margin: 0; 13 | background: #f9f9f9; 14 | font: 15px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; 15 | } 16 | * { 17 | -webkit-box-sizing: border-box; 18 | -moz-box-sizing: border-box; 19 | box-sizing: border-box; 20 | } 21 | h1 { 22 | font-size: 46px; 23 | margin: 0; 24 | padding: 10px 0; 25 | } 26 | a { 27 | text-decoration: none; 28 | color: #333; 29 | } 30 | .main { 31 | max-width: 600px; 32 | margin: 0 auto; 33 | text-align: center; 34 | background: #fff; 35 | -webkit-box-shadow: 0 0 5px #e2e2e2; 36 | -moz-box-shadow: 0 0 5px #e2e2e2; 37 | box-shadow: 0 0 5px #e2e2e2; 38 | border-left: 1px solid #e2e2e2; 39 | border-right: 1px solid #e2e2e2; 40 | } 41 | .button { 42 | margin: 10px; 43 | border: 1px solid #eee; 44 | outline: none; 45 | background: #f0f0f0; 46 | padding: 5px; 47 | } 48 | .button:hover { 49 | color: #fff; 50 | background: #4078c0; 51 | } 52 | pre { 53 | text-align: left; 54 | } 55 | code { 56 | overflow: hidden !important; 57 | } 58 | .footer { 59 | padding: 30px 0; 60 | } 61 | .insekai { 62 | color: #4078c0; 63 | } 64 | .element { 65 | height: 200px; 66 | background-color: #f5f2f0; 67 | border-radius: 3px; 68 | position: relative; 69 | } 70 | .sandbox { 71 | position: absolute; 72 | top: 50%; 73 | left: 50%; 74 | font-size: 24px; 75 | height: 40px; 76 | width: 100px; 77 | margin-left: -50px; 78 | margin-top: -20px; 79 | line-height: 40px; 80 | text-align: center; 81 | color: #999; 82 | text-shadow: 0 1px #fff; 83 | } 84 | .inner { 85 | padding: 10px; 86 | } 87 | .hey { 88 | background-color: #fff; 89 | border-radius: 33px; 90 | height: 33px; 91 | line-height: 33px; 92 | border: 1px solid #e2e2e2; 93 | padding: 0 20px; 94 | outline: none; 95 | } 96 | body 97 | .corner. 98 | 99 | .main 100 | h1 101 | a(href="/") Biu 102 | h2 Install 103 | :markdown 104 | ```bash 105 | # compatible with browserify and webpack 106 | $ npm install biu.js --save 107 | 108 | # then include the base styles 109 | # '})") Default 121 | button.button(onclick="biu('done!', {type: 'success', closeButton: ''})") Success 122 | button.button(onclick="biu('info not to be auto hidden', {type: 'info', autoHide: false})") Info 123 | button.button(onclick="biu('You are restricted to do this!', {type: 'warning'})") Warning 124 | button.button(onclick="biu('I will never go away, unless you force me to!', {type: 'danger', autoHide: false})") Danger 125 | button.button(onclick="biu('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Earum alias rem doloremque, iusto minus culpa ipsam deleniti, praesentium, quidem ratione soluta et. Blanditiis nemo dolorem, eius officia, aut explicabo culpa. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam autem repellendus nesciunt dolore, assumenda molestiae cum doloremque porro repudiandae magni quasi sequi, quos, incidunt ratione recusandae est. Deserunt, minus, perspiciatis.', {closeButton: '', autoHide: false, align: 'left', type: 'danger'})") Large 126 | h2 Advanced 127 | :markdown 128 | ```javascript 129 | // default options 130 | biu('', { 131 | type: 'default', 132 | // auto-hide in specific timeout 133 | autoHide: true, 134 | timeout: 3000, 135 | // hide immediately when clicked 136 | hideOnClick: false, 137 | // use font-awesome if you like! 138 | // closeButton: '', 139 | closeButton: '×', 140 | // where to append element 141 | el: document.body, 142 | // how to align text 143 | align: 'center', 144 | // whether to pop up the element in horizontal center 145 | pop: false, 146 | // trigger after element is hidden 147 | onHidden() {} 148 | }) 149 | ``` 150 | h2 Biu in elements other than body 151 | div.element#element 152 | span.sandbox 153 | button.hey(onclick="biu('Wow, how kimochi it is...',{autoHide:false,el: document.getElementById('element'),type:'success'})") Touch me 154 | h2 Trigger hide 155 | :markdown 156 | ```javascript 157 | const tip = biu('hello', {autoHide: false}) 158 | 159 | // when it's time to hide it, just call: 160 | tip.hide() 161 | ``` 162 | h2 Pop mode 163 | :markdown 164 | ```javascript 165 | biu('Neat one!', {pop: true}) 166 | ``` 167 | button.button(onclick="biu('Neat one!', {autoHide: false, pop: true, closeButton: ''})") Pop me! 168 | h2 Hide on click 169 | :markdown 170 | ```javascript 171 | biu('Wow, amazeballs!', {hideOnClick: true}) 172 | ``` 173 | button.button(onclick="biu('Wow, amazeballs!', {hideOnClick: true})") Click me! 174 | h2 Call function after the element is hidden but before it gets destroyed 175 | :markdown 176 | ```javascript 177 | biu('how is it?', { 178 | onHidden() { 179 | alert('bye!') 180 | } 181 | }) 182 | ``` 183 | button.button(onclick="biu('how is it?', {onHidden: function() {alert('bye')}})") Trigger! 184 | h2 Prompt user 185 | :markdown 186 | ```javascript 187 | const template = `Enter your name: 188 | ` 189 | 190 | const tip = biu(template, { 191 | autoHide: false, 192 | onHidden() { 193 | const name = document.querySelector('#prompt').value 194 | biu(`hello ${name}`, {pop: true}) 195 | } 196 | }) 197 | 198 | document.getElementById('ok').addEventListener('click', () => { 199 | tip.hide() 200 | }, false) 201 | ``` 202 | button.button(onclick="promptUser()") Prompt! 203 | footer.footer. 204 | Made with by EGOIST 205 | script(src="./biu.min.js?t=#{buildTime}") 206 | script(src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/prism.min.js") 207 | script(src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/components/prism-bash.min.js") 208 | script. 209 | function promptUser() { 210 | var html = 'Enter your name: ' 211 | var tip = biu(html, { 212 | autoHide: false, 213 | onHidden: function () { 214 | var name = document.querySelector('#prompt').value 215 | biu('hello ' + name, {pop: true}) 216 | } 217 | }) 218 | document.getElementById('ok').addEventListener('click', function () { 219 | tip.hide() 220 | }, false) 221 | } 222 | -------------------------------------------------------------------------------- /src/js/biu.js: -------------------------------------------------------------------------------- 1 | function isBody(el) { 2 | return el.toString && el.toString() === '[object HTMLBodyElement]' 3 | } 4 | class Biu { 5 | constructor(text, options) { 6 | this.text = text 7 | this.options = options 8 | this.el = document.createElement('div') 9 | this.el.className = `biu-instance biu-${options.type}` 10 | this.el.style.textAlign = this.options.align 11 | 12 | if (this.options.pop) { 13 | this.el.classList.add('biu-pop') 14 | } 15 | 16 | if (!isBody(this.options.el)) { 17 | this.options.el.style.overflow = 'hidden' 18 | this.options.el.style.position = 'relative' 19 | this.el.style.position = 'absolute' 20 | } 21 | 22 | // initial events 23 | this.events = {} 24 | 25 | // inner element 26 | this.insert() 27 | 28 | // auto hide animation 29 | if (this.options.autoHide !== false) { 30 | this.startTimer() 31 | } 32 | 33 | // mouse events 34 | this.registerEvents() 35 | } 36 | 37 | insert() { 38 | // close button 39 | this.closeButton = document.createElement('div') 40 | this.closeButton.className = 'biu-close' 41 | this.closeButton.innerHTML = this.options.closeButton 42 | this.el.appendChild(this.closeButton) 43 | 44 | // main 45 | const elMain = document.createElement('div') 46 | elMain.className = 'biu-main' 47 | elMain.innerHTML = this.text 48 | this.el.appendChild(elMain) 49 | 50 | this.options.el.appendChild(this.el) 51 | setTimeout(() => { 52 | this.el.classList.add('biu-shown') 53 | }, 200) 54 | } 55 | 56 | registerEvents() { 57 | if (this.options.autoHide !== false) { 58 | this.events.mouseover = () => this.stopTimer() 59 | this.events.mouseleave = () => this.startTimer() 60 | this.el.addEventListener('mouseover', this.events.mouseover, false) 61 | this.el.addEventListener('mouseleave', this.events.mouseleave, false) 62 | } 63 | 64 | this.events.hide = (event) => this.hide(event) 65 | 66 | if (this.options.hideOnClick) { 67 | this.el.addEventListener('click', this.events.hide, false) 68 | } else { 69 | this.closeButton.addEventListener('click', this.events.hide, false) 70 | } 71 | } 72 | 73 | startTimer(timeout = this.options.timeout) { 74 | this.timer = setTimeout(() => { 75 | this.hide() 76 | }, timeout) 77 | } 78 | 79 | stopTimer() { 80 | if (this.timer) { 81 | clearTimeout(this.timer) 82 | this.timer = null 83 | } 84 | } 85 | 86 | hide(event = {}) { 87 | if (!this.el || (event.target && event.target.tagName === 'A')) { 88 | return 89 | } 90 | 91 | if (this.options.pop) { 92 | this.el.style.transform = 'translateX(-50%) translateY(-110%)' 93 | } else { 94 | this.el.style.transform = 'translateY(-100%)' 95 | } 96 | setTimeout(() => { 97 | if (this.options.onHidden) { 98 | this.options.onHidden.call(this) 99 | } 100 | this.options.el.removeChild(this.el) 101 | this.el = null 102 | this.stopTimer() 103 | }, 300) 104 | } 105 | } 106 | 107 | function biu(text = '', { 108 | type = 'default', 109 | timeout = 3000, 110 | autoHide = true, 111 | hideOnClick = false, 112 | closeButton = '×', 113 | el = document.body, 114 | align = 'center', 115 | pop = false, 116 | onHidden 117 | } = {}) { 118 | return new Biu(text, { 119 | type, 120 | timeout, 121 | autoHide, 122 | closeButton, 123 | hideOnClick, 124 | el, 125 | align, 126 | pop, 127 | onHidden 128 | }) 129 | } 130 | 131 | export default biu 132 | -------------------------------------------------------------------------------- /src/styl/biu.styl: -------------------------------------------------------------------------------- 1 | .biu-instance 2 | top 0 3 | left 0 4 | right 0 5 | position fixed 6 | background-color white 7 | padding 10px 0 8 | border-bottom 1px solid #e2e2e2 9 | z-index 99999 10 | animation-name biu-down 11 | animation-duration .3s 12 | font-size 1rem 13 | transform translateY(-100%) 14 | transition transform .3s ease 15 | &.biu-pop 16 | width 400px 17 | max-width 80% 18 | left 50% 19 | right none 20 | transform translateX(-50%) translateY(-110%) 21 | box-shadow 0 1px 2px rgba(0,0,0,0.5) 22 | border-bottom none 23 | border-radius 0 0 2px 2px 24 | 25 | .biu-main 26 | padding 0 40px 0 20px 27 | word-wrap break-word 28 | 29 | .biu-close 30 | float right 31 | cursor pointer 32 | width 20px 33 | margin-right 10px 34 | border-radius 2px 35 | text-align center 36 | 37 | .biu-shown 38 | transform translateY(0) 39 | &.biu-pop 40 | transform translateX(-50%) translateY(0) 41 | 42 | .biu-success,.biu-info,biu-warning 43 | color white 44 | 45 | .biu-default 46 | color #333 47 | background-color white 48 | border-color #e2e2e2 49 | .biu-close 50 | &:hover 51 | background-color #e2e2e2 52 | 53 | .biu-success 54 | color #3c763d 55 | background-color #dff0d8 56 | border-color #d6e9c6 57 | .biu-close 58 | &:hover 59 | background-color #d6e9c6 60 | 61 | .biu-info 62 | color #31708f 63 | background-color #d9edf7 64 | border-color #bce8f1 65 | .biu-close 66 | &:hover 67 | background-color #bce8f1 68 | 69 | .biu-warning 70 | color #8a6d3b 71 | background-color #fcf8e3 72 | border-color #faebcc 73 | .biu-close 74 | &:hover 75 | background-color #faebcc 76 | 77 | .biu-danger 78 | color #a94442 79 | background-color #f2dede 80 | border-color #ebccd1 81 | .biu-close 82 | &:hover 83 | background-color #ebccd1 84 | --------------------------------------------------------------------------------