Skip to content

Commit bc185d8

Browse files
TheSharpieOneeddywashere
authored andcommitted
feat(Progress): add Progress component (#105)
Add Progress component which will output bootstrap's progress component Progress has `striped`, `animated`, and `color` props. It will default to `<progress>` with a `<div>` fallback for IE9 Overriding the tag will produce the fallback inside the custom tag. Closes #78
1 parent 869e523 commit bc185d8

13 files changed

Lines changed: 492 additions & 0 deletions
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
2+
import React from 'react';
3+
import { PrismCode } from 'react-prism';
4+
import Helmet from 'react-helmet';
5+
import { Card, CardText } from 'reactstrap';
6+
import ProgressExample from '../examples/Progress';
7+
const ProgressExampleSource = require('!!raw!../examples/Progress.jsx');
8+
import ProgressColorExample from '../examples/ProgressColor';
9+
const ProgressColorExampleSource = require('!!raw!../examples/ProgressColor.jsx');
10+
import ProgressAnimatedExample from '../examples/ProgressAnimated';
11+
const ProgressAnimatedExampleSource = require('!!raw!../examples/ProgressAnimated.jsx');
12+
import ProgressStripedExample from '../examples/ProgressStriped';
13+
const ProgressStripedExampleSource = require('!!raw!../examples/ProgressStriped.jsx');
14+
import ProgressMaxExample from '../examples/ProgressMax';
15+
const ProgressMaxExampleSource = require('!!raw!../examples/ProgressMax.jsx');
16+
17+
export default class ProgressPage extends React.Component {
18+
render() {
19+
return (
20+
<div>
21+
<Helmet title="Progress" />
22+
<h3>Progress</h3>
23+
<div className="docs-example">
24+
<ProgressExample />
25+
</div>
26+
<pre>
27+
<PrismCode className="language-jsx">
28+
{ProgressExampleSource}
29+
</PrismCode>
30+
</pre>
31+
<h4>Properties</h4>
32+
<pre>
33+
<PrismCode className="language-jsx">
34+
{`Progress.propTypes = {
35+
tag: PropTypes.string,
36+
value: PropTypes.oneOfType([
37+
PropTypes.string,
38+
PropTypes.number,
39+
]),
40+
max: PropTypes.oneOf([
41+
PropTypes.string,
42+
PropTypes.number,
43+
]),
44+
animated: PropTypes.bool,
45+
stripped: PropTypes.bool,
46+
color: PropTypes.string,
47+
className: PropTypes.any
48+
};
49+
50+
Progress.defaultProps = {
51+
tag: 'progress',
52+
value: 0,
53+
max: 100,
54+
};`}
55+
</PrismCode>
56+
</pre>
57+
58+
<h3>Color Variants</h3>
59+
<div className="docs-example">
60+
<div>
61+
<ProgressColorExample />
62+
</div>
63+
</div>
64+
<pre>
65+
<PrismCode className="language-jsx">
66+
{ProgressColorExampleSource}
67+
</PrismCode>
68+
</pre>
69+
70+
<h3>Striped</h3>
71+
<div className="docs-example">
72+
<div>
73+
<ProgressStripedExample />
74+
</div>
75+
</div>
76+
<pre>
77+
<PrismCode className="language-jsx">
78+
{ProgressStripedExampleSource}
79+
</PrismCode>
80+
</pre>
81+
82+
<h3>Animated</h3>
83+
<p>
84+
The <code>animated</code> prop also adds the <code>striped</code> prop; there is no need to pass both.
85+
</p>
86+
<Card block outline color="danger">
87+
<CardText>
88+
Currently, animated progress does not work in bootstrap v4 (alpha 3). This is an issue bootstrap has to
89+
resolve.
90+
</CardText>
91+
</Card>
92+
<div className="docs-example">
93+
<div>
94+
<ProgressAnimatedExample />
95+
</div>
96+
</div>
97+
<pre>
98+
<PrismCode className="language-jsx">
99+
{ProgressAnimatedExampleSource}
100+
</PrismCode>
101+
</pre>
102+
103+
<h3>Max value</h3>
104+
<div className="docs-example">
105+
<div>
106+
<ProgressMaxExample />
107+
</div>
108+
</div>
109+
<pre>
110+
<PrismCode className="language-jsx">
111+
{ProgressMaxExampleSource}
112+
</PrismCode>
113+
</pre>
114+
115+
</div>
116+
);
117+
}
118+
}

docs/lib/Components/index.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class Components extends React.Component {
7171
name: 'Popovers',
7272
to: '/components/popovers/'
7373
},
74+
{
75+
name: 'Progress',
76+
to: '/components/progress/'
77+
},
7478
{
7579
name: 'Modals',
7680
to: '/components/modals/'

docs/lib/examples/Progress.jsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import { Progress } from 'reactstrap';
3+
4+
const Example = (props) => {
5+
return (
6+
<div>
7+
<div className="text-xs-center">0%</div>
8+
<Progress />
9+
<div className="text-xs-center">25%</div>
10+
<Progress value="25" />
11+
<div className="text-xs-center">50%</div>
12+
<Progress value={50} />
13+
<div className="text-xs-center">75%</div>
14+
<Progress value={75} />
15+
<div className="text-xs-center">100%</div>
16+
<Progress value="100" />
17+
</div>
18+
);
19+
};
20+
21+
export default Example;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { Progress } from 'reactstrap';
3+
4+
const Example = (props) => {
5+
return (
6+
<div>
7+
<Progress animated value={2 * 5} />
8+
<Progress animated color="success" value="25" />
9+
<Progress animated color="info" value={50} />
10+
<Progress animated color="warning" value={75} />
11+
<Progress animated color="danger" value="100" />
12+
</div>
13+
);
14+
};
15+
16+
export default Example;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { Progress } from 'reactstrap';
3+
4+
const Example = (props) => {
5+
return (
6+
<div>
7+
<Progress value={2 * 5} />
8+
<Progress color="success" value="25" />
9+
<Progress color="info" value={50} />
10+
<Progress color="warning" value={75} />
11+
<Progress color="danger" value="100" />
12+
</div>
13+
);
14+
};
15+
16+
export default Example;

docs/lib/examples/ProgressMax.jsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import { Progress } from 'reactstrap';
3+
4+
const Example = (props) => {
5+
return (
6+
<div>
7+
<div className="text-xs-center">1 of 5</div>
8+
<Progress value="1" max="5" />
9+
<div className="text-xs-center">50 of 135</div>
10+
<Progress value={50} max="135" />
11+
<div className="text-xs-center">75 of 111</div>
12+
<Progress value={75} max={111} />
13+
<div className="text-xs-center">463 of 500</div>
14+
<Progress value="463" max={500} />
15+
</div>
16+
);
17+
};
18+
19+
export default Example;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { Progress } from 'reactstrap';
3+
4+
const Example = (props) => {
5+
return (
6+
<div>
7+
<Progress striped value={2 * 5} />
8+
<Progress striped color="success" value="25" />
9+
<Progress striped color="info" value={50} />
10+
<Progress striped color="warning" value={75} />
11+
<Progress striped color="danger" value="100" />
12+
</div>
13+
);
14+
};
15+
16+
export default Example;

docs/lib/routes.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import DropdownsPage from './Components/DropdownsPage';
1212
import FormPage from './Components/FormPage';
1313
import InputGroupPage from './Components/InputGroupPage';
1414
import PopoversPage from './Components/PopoversPage';
15+
import ProgressPage from './Components/ProgressPage';
1516
import TooltipsPage from './Components/TooltipsPage';
1617
import TagsPage from './Components/TagsPage';
1718
import MediaPage from './Components/MediaPage';
@@ -35,6 +36,7 @@ const routes = (
3536
<Route path="form/" component={FormPage} />
3637
<Route path="input-group/" component={InputGroupPage} />
3738
<Route path="popovers/" component={PopoversPage} />
39+
<Route path="progress/" component={ProgressPage} />
3840
<Route path="tooltips/" component={TooltipsPage} />
3941
<Route path="tags/" component={TagsPage} />
4042
<Route path="card/" component={CardPage} />

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"classnames": "^2.2.3",
4848
"lodash.isfunction": "^3.0.8",
4949
"lodash.omit": "^4.4.1",
50+
"lodash.tonumber": "^4.0.3",
5051
"tether": "^1.3.4"
5152
},
5253
"peerDependencies": {

src/Progress.jsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React, { PropTypes } from 'react';
2+
import classNames from 'classnames';
3+
import toNumber from 'lodash.tonumber';
4+
5+
const propTypes = {
6+
tag: PropTypes.string,
7+
value: PropTypes.oneOfType([
8+
PropTypes.string,
9+
PropTypes.number,
10+
]),
11+
max: PropTypes.oneOfType([
12+
PropTypes.string,
13+
PropTypes.number,
14+
]),
15+
animated: PropTypes.bool,
16+
striped: PropTypes.bool,
17+
color: PropTypes.string,
18+
className: PropTypes.any
19+
};
20+
21+
const defaultProps = {
22+
tag: 'progress',
23+
value: 0,
24+
max: 100,
25+
};
26+
27+
const Progress = (props) => {
28+
const {
29+
className,
30+
value,
31+
max,
32+
animated,
33+
striped,
34+
color,
35+
tag: Tag,
36+
...attributes
37+
} = props;
38+
39+
const percent = ((toNumber(value) / toNumber(max)) * 100);
40+
41+
const nonProgressClasses = classNames(
42+
className,
43+
'progress',
44+
animated ? 'progress-animated' : null
45+
);
46+
47+
const progressClasses = classNames(
48+
nonProgressClasses,
49+
color ? `progress-${color}` : null,
50+
striped || animated ? 'progress-striped' : null
51+
);
52+
53+
const fallbackClasses = classNames(
54+
'progress-bar',
55+
color ? `progress-${color}` : null,
56+
striped || animated ? 'progress-bar-striped' : null
57+
);
58+
59+
const fallbackFill = (
60+
<span
61+
className={fallbackClasses}
62+
style={{ width: `${percent}%` }}
63+
role="progressbar"
64+
aria-valuenow={value}
65+
aria-valuemin="0"
66+
aria-valuemax={max}
67+
/>
68+
);
69+
70+
if (Tag === 'progress') {
71+
return (
72+
<Tag {...attributes} className={progressClasses} value={value} max={max}>
73+
<div className={nonProgressClasses} children={fallbackFill} />
74+
</Tag>
75+
);
76+
}
77+
78+
return (
79+
<Tag {...attributes} className={nonProgressClasses} children={fallbackFill} />
80+
);
81+
};
82+
83+
Progress.propTypes = propTypes;
84+
Progress.defaultProps = defaultProps;
85+
86+
export default Progress;

0 commit comments

Comments
 (0)