├── .editorconfig ├── .gitignore ├── dist ├── preact-progress.js └── preact-progress.min.js ├── license ├── package.json ├── readme.md ├── rollup.config.js └── src └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{json,yml,md}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | *.log 4 | -------------------------------------------------------------------------------- /dist/preact-progress.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('preact')) : 3 | typeof define === 'function' && define.amd ? define(['preact'], factory) : 4 | (global.Progress = factory(global.preact)); 5 | }(this, (function (preact) { 'use strict'; 6 | 7 | var STYLE_OUTER = 'width:100%;z-index:9999;top:0'; 8 | var STLYE_INNER = 'width:0;height:100%'; 9 | var limit = function (v) { return Math.min(v || 0, 100); }; 10 | 11 | var Progress = (function (Component$$1) { 12 | function Progress(props) { 13 | Component$$1.call(this, props); 14 | 15 | this.state = { 16 | val: limit(props.value) 17 | }; 18 | } 19 | 20 | if ( Component$$1 ) Progress.__proto__ = Component$$1; 21 | Progress.prototype = Object.create( Component$$1 && Component$$1.prototype ); 22 | Progress.prototype.constructor = Progress; 23 | 24 | Progress.prototype.componentDidMount = function componentDidMount () { 25 | (this.props.onStart || this.props.onChange)(this, this.state.val); 26 | }; 27 | 28 | Progress.prototype.componentWillReceiveProps = function componentWillReceiveProps (ref) { 29 | var value = ref.value; 30 | 31 | this.setState({val: limit(value)}); 32 | }; 33 | 34 | Progress.prototype.componentDidUpdate = function componentDidUpdate (ref) { 35 | var onChange = ref.onChange; 36 | var onComplete = ref.onComplete; 37 | 38 | var val = this.state.val; 39 | (val >= 100) ? (onComplete && onComplete(this)) : (onChange && onChange(this, val)); 40 | }; 41 | 42 | Progress.prototype.render = function render (ref, ref$1) { 43 | var id = ref.id; 44 | var className = ref.className; 45 | var height = ref.height; if ( height === void 0 ) height = '4px'; 46 | var color = ref.color; if ( color === void 0 ) color = 'black'; 47 | var val = ref$1.val; 48 | 49 | return ( 50 | preact.h( 'div', { id: id, className: className, style: (STYLE_OUTER + ";height:" + height + ";") }, 51 | preact.h( 'div', { style: (STLYE_INNER + ";background-color:" + color + ";width:" + val + "%;transition:all 200ms ease;") }) 52 | ) 53 | ) 54 | }; 55 | 56 | return Progress; 57 | }(preact.Component)); 58 | 59 | return Progress; 60 | 61 | }))); 62 | -------------------------------------------------------------------------------- /dist/preact-progress.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("preact")):"function"==typeof define&&define.amd?define(["preact"],e):t.Progress=e(t.preact)}(this,function(t){"use strict";var e="width:100%;z-index:9999;top:0",o="width:0;height:100%",n=function(t){return Math.min(t||0,100)},i=function(i){function r(t){i.call(this,t),this.state={val:n(t.value)}}return i&&(r.__proto__=i),r.prototype=Object.create(i&&i.prototype),r.prototype.constructor=r,r.prototype.componentDidMount=function(){(this.props.onStart||this.props.onChange)(this,this.state.val)},r.prototype.componentWillReceiveProps=function(t){var e=t.value;this.setState({val:n(e)})},r.prototype.componentDidUpdate=function(t){var e=t.onChange,o=t.onComplete,n=this.state.val;n>=100?o&&o(this):e&&e(this,n)},r.prototype.render=function(n,i){var r=n.id,a=n.className,p=n.height;void 0===p&&(p="4px");var s=n.color;void 0===s&&(s="black");var c=i.val;return t.h("div",{id:r,className:a,style:e+";height:"+p+";"},t.h("div",{style:o+";background-color:"+s+";width:"+c+"%;transition:all 200ms ease;"}))},r}(t.Component);return i}); -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Luke Edwards (https://lukeed.com) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "preact-progress", 3 | "version": "1.0.0", 4 | "module": "src/index.js", 5 | "main": "dist/preact-progress.js", 6 | "repository": "lukeed/preact-progress", 7 | "description": "Simple and lightweight (~590 bytes gzip) progress bar component for Preact", 8 | "license": "MIT", 9 | "files": [ 10 | "src", 11 | "dist" 12 | ], 13 | "author": { 14 | "name": "Luke Edwards", 15 | "email": "luke.edwards05@gmail.com", 16 | "url": "https://lukeed.com" 17 | }, 18 | "scripts": { 19 | "build": "rollup -c", 20 | "postbuild": "uglifyjs dist/preact-progress.js -c -m -o dist/preact-progress.min.js" 21 | }, 22 | "devDependencies": { 23 | "rollup": "^0.41.4", 24 | "rollup-plugin-buble": "^0.15.0", 25 | "uglify-js": "^2.7.5" 26 | }, 27 | "peerDependencies": { 28 | "preact": "^7.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # preact-progress [![NPM](https://img.shields.io/npm/v/preact-progress.svg)](https://www.npmjs.com/package/preact-progress) 2 | 3 | > Simple and lightweight (~590 bytes gzip) progress bar component; for :atom_symbol: [Preact](https://github.com/developit/preact) 4 | 5 | #### [Demo](https://jsfiddle.net/lukeed/kws8r5v4/) 6 | 7 | ## Install 8 | 9 | ``` 10 | $ npm install --save preact-progress 11 | ``` 12 | 13 | > :exclamation: **Pro Tip:** Use [Yarn](https://yarnpkg.com/) to install dependencies 3x faster than NPM! 14 | 15 | ```html 16 | 17 | ``` 18 | 19 | ## Usage 20 | 21 | Provide a `value`; everything else is optional. 22 | 23 | ```js 24 | import { h } from 'preact'; 25 | import Progress from 'preact-progress'; 26 | 27 | onChange = (ctx, val) => console.log(`${val}% complete`); 28 | onComplete = ctx => {ctx.base.style.opacity = 0}; 29 | 30 | 36 | ``` 37 | 38 | ## Properties 39 | 40 | #### value 41 | Type: `Number`
42 | Default: `0`
43 | The current progress; between 0 and 100. Mapped to a `style:width` percentage. 44 | 45 | #### onStart 46 | Type: `Function`
47 | The callback function when progress bar mounts. Receives the current `Progress` component as its first argument & the current `value` as its second argument. 48 | 49 | #### onChange 50 | Type: `Function`
51 | The callback function whenever the progress value updates. Receives the current `Progress` component as its first argument & the current `value` as its second argument. 52 | 53 | #### onComplete 54 | Type: `Function`
55 | The callback function when progress bar has reached 100%. Receives the current `Progress` component as its only argument. 56 | 57 | #### height 58 | Type: `String`
59 | Default: `4px`
60 | The height of the animated progress bar. 61 | 62 | #### color 63 | Type: `String`
64 | Default: `black`
65 | The color of the animated progress bar. 66 | 67 | #### id 68 | Type: `String`
69 | Default: `none`
70 | The `id` attribute to pass down. 71 | 72 | #### className 73 | Type: `String`
74 | Default: `none`
75 | The `className` attribute to pass down. Added to the wrapper element. 76 | 77 | ## License 78 | 79 | MIT © [Luke Edwards](https://lukeed.com) 80 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import buble from 'rollup-plugin-buble'; 2 | 3 | export default { 4 | entry: 'src/index.js', 5 | dest: 'dist/preact-progress.js', 6 | moduleName: 'Progress', 7 | external: ['preact'], 8 | format: 'umd', 9 | plugins: [ 10 | buble({ 11 | jsx: 'h', 12 | transforms: { 13 | modules: false 14 | } 15 | }) 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { h, Component } from 'preact'; 2 | 3 | const STYLE_OUTER = 'width:100%;z-index:9999;top:0'; 4 | const STLYE_INNER = 'width:0;height:100%'; 5 | const limit = v => Math.min(v || 0, 100); 6 | 7 | export default class Progress extends Component { 8 | constructor(props) { 9 | super(props); 10 | 11 | this.state = { 12 | val: limit(props.value) 13 | }; 14 | } 15 | 16 | componentDidMount() { 17 | (this.props.onStart || this.props.onChange)(this, this.state.val); 18 | } 19 | 20 | componentWillReceiveProps({ value }) { 21 | this.setState({val: limit(value)}); 22 | } 23 | 24 | componentDidUpdate({ onChange, onComplete }) { 25 | const val = this.state.val; 26 | (val >= 100) ? (onComplete && onComplete(this)) : (onChange && onChange(this, val)); 27 | } 28 | 29 | render({ id, className, height='4px', color='black' }, { val }) { 30 | return ( 31 |
32 |
33 |
34 | ) 35 | } 36 | } 37 | --------------------------------------------------------------------------------