Socket
Socket
Sign inDemoInstall

react-circular-progressbar

Package Overview
Dependencies
6
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.1 to 1.0.0

59

CHANGELOG.md

@@ -0,1 +1,60 @@

## 1.0.0
We're at 1.0.0! 🎉 Thank you to all the contributors and issue creators.
The main breaking change is the replacement of the `classForPercentage` prop with `className`, and the `textForPercentage` prop with `text` [#61].
**How to migrate**:
Previously, the text would by default display as "{yourPercentage}%". With 1.0, if you want to display that text, you need to supply the `text` prop explicitly:
```jsx
const percentage = 60;
<CircularProgressbar
percentage={percentage}
text={`${percentage}%`}
/>
```
If you had customized either `classForPercentage` or `textForPercentage` functions before 1.0, you can reuse the same function for `className` and `text`.
So if your pre-1.0 usage looked like this:
```jsx
function customClassForPercentage(percentage) {
if (percentage < 50) {
return 'red';
} else {
return 'blue';
}
}
function customTextForPercentage(percentage) {
if (percentage === 100) {
return `${percentage}!!!`;
} else {
return `${percentage}%`;
}
}
const percentage = 60;
<CircularProgressbar
percentage={percentage}
classForPercentage={customClassForPercentage}
textForPercentage={customTextForPercentage}
/>
```
...you can make a small change to make it work in 1.0:
```jsx
<CircularProgressbar
percentage={percentage}
className={customClassForPercentage()}
text={customTextForPercentage()}
/>
```
## 0.8.1

@@ -2,0 +61,0 @@

2

dist/index.js

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.CircularProgressbar=t(require("react")):e.CircularProgressbar=t(e.React)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=7)}([function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),u=r(6),c=n(u),l=r(4),p=n(l),f=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.state={percentage:e.initialAnimation?0:e.percentage},r}return i(t,e),s(t,[{key:"componentDidMount",value:function(){var e=this;this.props.initialAnimation&&(this.initialTimeout=setTimeout(function(){e.requestAnimationFrame=window.requestAnimationFrame(function(){e.setState({percentage:e.props.percentage})})},0))}},{key:"componentWillReceiveProps",value:function(e){this.setState({percentage:e.percentage})}},{key:"componentWillUnmount",value:function(){clearTimeout(this.initialTimeout),window.cancelAnimationFrame(this.requestAnimationFrame)}},{key:"getBackgroundPadding",value:function(){return this.props.background?null==this.props.backgroundPadding?this.props.strokeWidth:this.props.backgroundPadding:0}},{key:"getPathDescription",value:function(){var e=this.getPathRadius(),t=this.props.counterClockwise?1:0;return"\n M 50,50\n m 0,-"+e+"\n a "+e+","+e+" "+t+" 1 1 0,"+2*e+"\n a "+e+","+e+" "+t+" 1 1 0,-"+2*e+"\n "}},{key:"getPathStyles",value:function(){var e=2*Math.PI*this.getPathRadius(),t=Math.min(Math.max(this.state.percentage,0),100),r=(100-t)/100*e;return{strokeDasharray:e+"px "+e+"px",strokeDashoffset:(this.props.counterClockwise?-r:r)+"px"}}},{key:"getPathRadius",value:function(){return 50-this.props.strokeWidth/2-this.getBackgroundPadding()}},{key:"render",value:function(){var e=this.props,t=e.percentage,r=e.textForPercentage,n=e.className,o=e.classes,a=e.styles,i=e.strokeWidth,s=this.props.classForPercentage?this.props.classForPercentage(t):"",u=this.getPathDescription(),l=r?r(t):null;return c.default.createElement("svg",{className:o.root+" "+n+" "+s,style:a.root,viewBox:"0 0 100 100"},this.props.background?c.default.createElement("circle",{className:o.background,style:a.background,cx:50,cy:50,r:50}):null,c.default.createElement("path",{className:o.trail,style:a.trail,d:u,strokeWidth:i,fillOpacity:0}),c.default.createElement("path",{className:o.path,d:u,strokeWidth:i,fillOpacity:0,style:Object.assign({},a.path,this.getPathStyles())}),l?c.default.createElement("text",{className:o.text,style:a.text,x:50,y:50},l):null)}}]),t}(c.default.Component);f.propTypes={percentage:p.default.number.isRequired,className:p.default.string,classes:p.default.objectOf(p.default.string),styles:p.default.objectOf(p.default.object),strokeWidth:p.default.number,background:p.default.bool,backgroundPadding:p.default.number,initialAnimation:p.default.bool,counterClockwise:p.default.bool,classForPercentage:p.default.func,textForPercentage:p.default.func},f.defaultProps={strokeWidth:8,className:"",classes:{root:"CircularProgressbar",trail:"CircularProgressbar-trail",path:"CircularProgressbar-path",text:"CircularProgressbar-text",background:"CircularProgressbar-background"},styles:{root:{},trail:{},path:{},text:{},background:{}},background:!1,backgroundPadding:null,initialAnimation:!1,counterClockwise:!1,classForPercentage:null,textForPercentage:function(e){return e+"%"}},t.default=f},function(e,t,r){"use strict";function n(e){return function(){return e}}var o=function(){};o.thatReturns=n,o.thatReturnsFalse=n(!1),o.thatReturnsTrue=n(!0),o.thatReturnsNull=n(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,r){"use strict";function n(e,t,r,n,a,i,s,u){if(o(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[r,n,a,i,s,u],p=0;c=new Error(t.replace(/%s/g,function(){return l[p++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var o=function(e){};e.exports=n},function(e,t,r){"use strict";var n=r(1),o=r(2),a=r(5);e.exports=function(){function e(e,t,r,n,i,s){s!==a&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t,r){e.exports=r(3)()},function(e,t,r){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(t,r){t.exports=e},function(e,t,r){e.exports=r(0)}])});
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.CircularProgressbar=t(require("react")):e.CircularProgressbar=t(e.React)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=7)}([function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),u=r(6),c=n(u),l=r(4),p=n(l),f=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.state={percentage:e.initialAnimation?0:e.percentage},r}return i(t,e),s(t,[{key:"componentDidMount",value:function(){var e=this;this.props.initialAnimation&&(this.initialTimeout=setTimeout(function(){e.requestAnimationFrame=window.requestAnimationFrame(function(){e.setState({percentage:e.props.percentage})})},0))}},{key:"componentWillReceiveProps",value:function(e){this.setState({percentage:e.percentage})}},{key:"componentWillUnmount",value:function(){clearTimeout(this.initialTimeout),window.cancelAnimationFrame(this.requestAnimationFrame)}},{key:"getBackgroundPadding",value:function(){return this.props.background?null==this.props.backgroundPadding?this.props.strokeWidth:this.props.backgroundPadding:0}},{key:"getPathDescription",value:function(){var e=this.getPathRadius(),t=this.props.counterClockwise?1:0;return"\n M 50,50\n m 0,-"+e+"\n a "+e+","+e+" "+t+" 1 1 0,"+2*e+"\n a "+e+","+e+" "+t+" 1 1 0,-"+2*e+"\n "}},{key:"getPathStyles",value:function(){var e=2*Math.PI*this.getPathRadius(),t=Math.min(Math.max(this.state.percentage,0),100),r=(100-t)/100*e;return{strokeDasharray:e+"px "+e+"px",strokeDashoffset:(this.props.counterClockwise?-r:r)+"px"}}},{key:"getPathRadius",value:function(){return 50-this.props.strokeWidth/2-this.getBackgroundPadding()}},{key:"render",value:function(){var e=this.props,t=(e.percentage,e.className),r=e.classes,n=e.styles,o=e.strokeWidth,a=e.text,i=this.getPathDescription();return c.default.createElement("svg",{className:r.root+" "+t,style:n.root,viewBox:"0 0 100 100"},this.props.background?c.default.createElement("circle",{className:r.background,style:n.background,cx:50,cy:50,r:50}):null,c.default.createElement("path",{className:r.trail,style:n.trail,d:i,strokeWidth:o,fillOpacity:0}),c.default.createElement("path",{className:r.path,d:i,strokeWidth:o,fillOpacity:0,style:Object.assign({},n.path,this.getPathStyles())}),a?c.default.createElement("text",{className:r.text,style:n.text,x:50,y:50},a):null)}}]),t}(c.default.Component);f.propTypes={percentage:p.default.number.isRequired,className:p.default.string,text:p.default.string,classes:p.default.objectOf(p.default.string),styles:p.default.objectOf(p.default.object),strokeWidth:p.default.number,background:p.default.bool,backgroundPadding:p.default.number,initialAnimation:p.default.bool,counterClockwise:p.default.bool},f.defaultProps={strokeWidth:8,className:"",text:null,classes:{root:"CircularProgressbar",trail:"CircularProgressbar-trail",path:"CircularProgressbar-path",text:"CircularProgressbar-text",background:"CircularProgressbar-background"},styles:{root:{},trail:{},path:{},text:{},background:{}},background:!1,backgroundPadding:null,initialAnimation:!1,counterClockwise:!1},t.default=f},function(e,t,r){"use strict";function n(e){return function(){return e}}var o=function(){};o.thatReturns=n,o.thatReturnsFalse=n(!1),o.thatReturnsTrue=n(!0),o.thatReturnsNull=n(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,r){"use strict";function n(e,t,r,n,a,i,s,u){if(o(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[r,n,a,i,s,u],p=0;c=new Error(t.replace(/%s/g,function(){return l[p++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var o=function(e){};e.exports=n},function(e,t,r){"use strict";var n=r(1),o=r(2),a=r(5);e.exports=function(){function e(e,t,r,n,i,s){s!==a&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t,r){e.exports=r(3)()},function(e,t,r){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(t,r){t.exports=e},function(e,t,r){e.exports=r(0)}])});
{
"name": "react-circular-progressbar",
"version": "0.8.1",
"version": "1.0.0",
"description": "A circular progress indicator component",

@@ -5,0 +5,0 @@ "author": "Kevin Qi <iqnivek@gmail.com>",

# React Circular Progressbar
A circular progress indicator component, built with SVG. Easily customizable with CSS. [See a live demo](http://www.kevinqi.com/react-circular-progressbar/).
[![npm version](https://badge.fury.io/js/react-circular-progressbar.svg)](https://badge.fury.io/js/react-circular-progressbar)
[![npm version](https://badge.fury.io/js/react-circular-progressbar.svg)](https://www.npmjs.com/package/react-circular-progressbar)
[![Build Status](https://travis-ci.org/iqnivek/react-circular-progressbar.svg?branch=master)](https://travis-ci.org/iqnivek/react-circular-progressbar)
[![Bundle size](https://img.shields.io/bundlephobia/min/react-circular-progressbar.svg)](https://bundlephobia.com/result?p=react-circular-progressbar)
[![react-circular-progressbar animated gif](/docs/react-circular-progressbar.gif?raw=true)](http://www.kevinqi.com/react-circular-progressbar/)
A circular progressbar component, built with SVG and extensively customizable.
[Try it out on CodeSandbox](https://codesandbox.io/s/vymm4oln6y).
<a href="https://codesandbox.io/s/vymm4oln6y"><img height="120" src="/docs/animated-progressbar.gif?raw=true" alt="animated progressbar" /></a> <a href="https://codesandbox.io/s/vymm4oln6y"><img height="120" src="/docs/circular-progressbar-examples.png?raw=true" alt="progressbar examples" /></a>
## Installation

@@ -38,15 +41,18 @@

If not, you can copy [styles.css](dist/styles.css) into your project instead and use `<link rel="stylesheet" href="styles.css" />` in your `<head>`.
If not, you can copy [styles.css](dist/styles.css) into your project instead, and include `<link rel="stylesheet" href="styles.css" />` in your `<head>`.
Now you can use the component:
```javascript
<CircularProgressbar percentage={60} />
```jsx
const percentage = 66;
<CircularProgressbar
percentage={percentage}
text={`${percentage}%`}
/>
```
You can play around with a working example on CodeSandbox: https://codesandbox.io/s/vymm4oln6y
## Props
For examples of how to use props, take a look at the [demo code](docs/demo.jsx) to see JSX for the [live demo page](http://www.kevinqi.com/react-circular-progressbar/).
[**Take a look at the CodeSandbox**](https://codesandbox.io/s/vymm4oln6y) for interactive examples on how to use these props.

@@ -56,38 +62,29 @@ | Name | Description |

| `percentage` | Numeric percentage to display, from 0-100. Required. |
| `className` | Classes to apply to the svg element |
| `className` | Classes to apply to the svg element. Default: `''`. |
| `text` | Text to display inside progressbar. Default: `null`. |
| `strokeWidth` | Width of circular line as a percentage relative to total width of component. Default: `8`. |
| `background` | Whether to display background color. Default: `false`. |
| `backgroundPadding` | Padding between background and edge of svg as a percentage relative to total width of component. Default: `0`. |
| `backgroundPadding` | Padding between background and edge of svg as a percentage relative to total width of component. Default: `null`. |
| `initialAnimation` | Toggle whether to animate progress starting from 0% on initial mount. Default: `false`. |
| `counterClockwise` | Toggle whether to rotate progressbar in counterclockwise direction. Default: `false`. |
| `classForPercentage` | Function which returns an additional class to apply to top-level svg element, which can be used for coloring/styling percentage ranges differently. Example: `(percent) => percent < 100 ? 'incomplete' : 'complete'`. |
| `textForPercentage` | Function which returns text to display, can be configured based on percentage. Example: ``(pct) => `${pct}%` ``. |
| `classes` | Object allowing overrides of classNames of each svg subcomponent (root, trail, path, text, background). Enables styling with react-jss. See [this PR](https://github.com/iqnivek/react-circular-progressbar/pull/25) for more detail. |
| `styles` | Object allowing customization of styles of each svg subcomponent (root, trail, path, text, background). |
Version 1.0.0 removed the `classForPercentage` and `textForPercentage` props in favor of the newer `className` and `text` props. Take a look at the [migration guide](/CHANGELOG.md) for instructions on how to migrate.
## Customizing styles
Use plain CSS to customize the styling - the default CSS is a good starting point, but you can override it as needed.
Use CSS or inline styles to customize the styling - the default CSS is a good starting point, but you can override it as needed.
#### CSS hooks
There are CSS hooks for the path, trail, text, and background of the progressbar which you can customize, e.g.:
```css
.CircularProgressbar-path { stroke: red; }
.CircularProgressbar-trail { stroke: gray; }
.CircularProgressbar-text { fill: yellow; }
.CircularProgressbar-background { fill: green; }
```
#### Inline style hooks
There are hooks to customize the inline styles of subcomponents of the progressbar (root, path, trail, text, and background). For example, to make the path colored dynamically based on percentage:
There are hooks to customize the inline styles of each subcomponent of the progressbar (the root svg, path, trail, text, and background).
```jsx
<CircularProgressbar
percentage={yourPercentage}
percentage={percentage}
text={`${percentage}%`}
styles={{
path: { stroke: `rgba(62, 152, 199, ${yourPercentage / 100})` },
path: { stroke: `rgba(62, 152, 199, ${percentage / 100})` },
text: { fill: '#f88', fontSize: '16px' },
}}

@@ -97,14 +94,21 @@ />

#### Using multiple themes
See `StyledProgressbar.js` in the [CodeSandbox examples](https://codesandbox.io/s/vymm4oln6y) for in-depth examples on how to customize these styles.
You can use the `className` prop to add different classes to the top-level SVG element, and then use that to add different themes to different instances, e.g.:
#### CSS hooks
```javascript
<CircularProgressbar percentage={25} className="progressbar-red" />
<CircularProgressbar percentage={25} className="progressbar-blue" />
There are equivalent CSS hooks for the root, path, trail, text, and background of the progressbar which you can customize.
If you're importing the default styles, you can override the defaults like this:
```jsx
import 'react-circular-progressbar/dist/styles.css';
import './custom.css';
```
```css
.progressbar-red .CircularProgressbar-path { stroke: red; }
.progressbar-blue .CircularProgressbar-path { stroke: blue; }
// custom.css
.CircularProgressbar-path { stroke: red; }
.CircularProgressbar-trail { stroke: gray; }
.CircularProgressbar-text { fill: yellow; }
.CircularProgressbar-background { fill: green; }
```

@@ -122,11 +126,9 @@

## Development
## Contributing
To run demo locally on localhost:8080:
Take a look at [CONTRIBUTING.md](/CONTRIBUTING.md) to see how to develop on react-circular-progressbar.
```bash
yarn install
yarn start
```
Keep tests passing by running `yarn test` and `yarn run lint`.
## License
[MIT](/LICENSE)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc