├── .gitignore
├── README.md
├── index.js
├── package.json
└── store.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | logs
3 | *.log
4 | npm-debug.log*
5 | .DS_Store
6 |
7 | dist/
8 | package-lock.json
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # bar-component [![stability][0]][1]
2 | [![npm version][2]][3] [![build status][4]][5]
3 | [![downloads][8]][9] [![js-standard-style][10]][11]
4 |
5 | tiny loading bar component
6 |
7 | ## Installation
8 |
9 | ```
10 | $ npm install bar-component
11 | ```
12 |
13 | ## Usage
14 |
15 | ```js
16 | // index.js
17 | var choo = require('choo')
18 | var html = require('choo/html')
19 | var Bar = require('bar-component')
20 | var bar = new Bar()
21 |
22 | var app = choo()
23 |
24 | app.use(require('bar-component/store')())
25 |
26 | app.route('/', (state, emit) => {
27 | return html`
28 | Hello
29 | ${bar.render(state.__progress)}
30 | `
31 | })
32 |
33 | app.mount('body')
34 | ```
35 |
36 | [0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square
37 | [1]: https://nodejs.org/api/documentation.html#documentation_stability_index
38 | [2]: https://img.shields.io/npm/v/bar-component.svg?style=flat-square
39 | [3]: https://npmjs.org/package/bar-component
40 | [4]: https://img.shields.io/travis/s3ththompson/bar-component/master.svg?style=flat-square
41 | [5]: https://travis-ci.org/s3ththompson/bar-component
42 | [8]: http://img.shields.io/npm/dm/bar-component.svg?style=flat-square
43 | [9]: https://npmjs.org/package/bar-component
44 | [10]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
45 | [11]: https://github.com/feross/standard
46 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var Nanocomponent = require('nanocomponent')
2 | var html = require('bel')
3 | var xtend = require('xtend')
4 |
5 | module.exports = Bar
6 |
7 | function Bar () {
8 | if (!(this instanceof Bar)) return new Bar()
9 | Nanocomponent.call(this)
10 | }
11 |
12 | Bar.prototype = Object.create(Nanocomponent.prototype)
13 |
14 | Bar.identity = function () {
15 | return 'unique'
16 | }
17 |
18 | Bar.prototype.createElement = function (progress, color, height) {
19 | return html``
20 | }
21 |
22 | Bar.prototype.update = function (progress, color, height) {
23 | if (this.element) {
24 | this.element.setAttribute('style', css(progress, color, height))
25 | }
26 | return false
27 | }
28 |
29 | function css (progress, color, height) {
30 | var styles = `transition: all 200ms ease;
31 | position: fixed;
32 | z-index: 9999;
33 | top: 0;
34 | left: 0;
35 | width: 100%;`
36 | if (progress == null) return styles + 'transition: none; ' + translate(-100)
37 | if (!color) color = '#000'
38 | if (!height) height = '2px'
39 | if (Number.isInteger(height)) height += 'px'
40 | return (
41 | styles +
42 | translate(100 * (progress - 1)) +
43 | ` background-color: ${color}; height: ${height};`
44 | )
45 | }
46 |
47 | function translate (percentage) {
48 | return `-webkit-transform: translate3d(${percentage}%, 0px, 0px);
49 | -ms-transform: translate3d(${percentage}%, 0px, 0px);
50 | transform: translate3d(${percentage}%, 0px, 0px);`
51 | }
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bar-component",
3 | "version": "1.0.1",
4 | "description": "tiny loading bar component",
5 | "main": "index.js",
6 | "scripts": {
7 | "fmt": "prettier-standard '**/*.js'",
8 | "test": "npm run fmt"
9 | },
10 | "author": "Seth Thompson (https://seththompson.org)",
11 | "repository": "s3ththompson/bar-component",
12 | "license": "MIT",
13 | "dependencies": {
14 | "bel": "^5.1.5",
15 | "nanocomponent": "^6.5.0",
16 | "xtend": "^4.0.1"
17 | },
18 | "devDependencies": {
19 | "prettier-standard": "^8.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/store.js:
--------------------------------------------------------------------------------
1 | var TRICKLE_SPEED = 200
2 | var _trickle
3 |
4 | module.exports = function () {
5 | return function (state, emitter) {
6 | emitter.on('progress:start', start)
7 | emitter.on('progress:done', done)
8 | emitter.on('progress:remove', remove)
9 | emitter.on('progress:set', set)
10 | emitter.on('progress:inc', inc)
11 |
12 | function start () {
13 | set(0)
14 |
15 | _trickle = setInterval(function () {
16 | inc()
17 | }, TRICKLE_SPEED)
18 | }
19 |
20 | function done () {
21 | inc(0.3 + 0.5 * Math.random())
22 | set(1)
23 | }
24 |
25 | function remove () {
26 | state.__progress = null
27 | render()
28 | }
29 |
30 | function set (n) {
31 | n = clamp(n, 0, 1)
32 | state.__progress = n
33 | render()
34 | if (n == 1) {
35 | clearInterval(_trickle)
36 | // wait for animation to finish then clear
37 | setTimeout(function () {
38 | state.__progress = null
39 | render()
40 | }, 200)
41 | }
42 | }
43 |
44 | function inc (amount) {
45 | var n = state.__progress
46 | if (n == null) {
47 | return start()
48 | } else if (n == 1) {
49 | } else {
50 | // trickle amounts from NProgress, (c) 2013, 2014 Rico Sta. Cruz
51 | // http://ricostacruz.com/nprogress
52 | if (typeof amount !== 'number') {
53 | if (n >= 0 && n < 0.2) {
54 | amount = 0.1
55 | } else if (n >= 0.2 && n < 0.5) {
56 | amount = 0.04
57 | } else if (n >= 0.5 && n < 0.8) {
58 | amount = 0.02
59 | } else if (n >= 0.8 && n < 0.99) {
60 | amount = 0.005
61 | } else {
62 | amount = 0
63 | }
64 | }
65 | n = clamp(n + amount, 0, 0.994)
66 | return set(n)
67 | }
68 | }
69 |
70 | function render () {
71 | emitter.emit('render')
72 | }
73 | }
74 | }
75 |
76 | function clamp (n, min, max) {
77 | if (n < min) return min
78 | if (n > max) return max
79 | return n
80 | }
81 |
--------------------------------------------------------------------------------