├── .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 [](https://npmjs.com/package/biu.js) [](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 |
--------------------------------------------------------------------------------