Browse Source

Implement ProgressBar & ProgressCircle

gre-patch-1
meriadec 6 years ago
parent
commit
d2cff7023c
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 65
      src/components/ProgressBar/index.js
  2. 16
      src/components/ProgressBar/stories.js
  3. 98
      src/components/ProgressCircle/index.js
  4. 16
      src/components/ProgressCircle/stories.js

65
src/components/ProgressBar/index.js

@ -0,0 +1,65 @@
// @flow
import React, { PureComponent } from 'react'
import styled, { css, keyframes } from 'styled-components'
import { colors } from 'styles/theme'
const animIndeterminate = keyframes`
0% {
transform: scaleX(0) translate3d(0, 0, 0);
}
50% {
transform: scaleX(1) translate3d(100%, 0, 0);
}
100% {
transform: scaleX(0) translate3d(0, 0, 0);
}
`
const Outer = styled.div`
background-color: ${colors.fog};
border-radius: 3px;
overflow: hidden;
height: 10px;
width: ${p => p.width}px;
position: relative;
`
const Inner = styled.div`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${colors.wallet};
transform-origin: center left;
${p =>
p.progress === 0
? css`
animation: ${animIndeterminate} 2s cubic-bezier(0.61, 0.01, 0.39, 1.03) infinite;
`
: css`
transform: scaleX(${p => p.progress});
transition: 150ms ease-out transform;
`};
`
type Props = {
progress: number,
width: number,
}
class ProgressBar extends PureComponent<Props> {
render() {
const { progress, width } = this.props
return (
<Outer width={width}>
<Inner progress={progress} />
</Outer>
)
}
}
export default ProgressBar

16
src/components/ProgressBar/stories.js

@ -0,0 +1,16 @@
// @flow
import React from 'react'
import { storiesOf } from '@storybook/react'
import { number } from '@storybook/addon-knobs'
import ProgressBar from 'components/ProgressBar'
const stories = storiesOf('Components', module)
stories.add('ProgressBar', () => (
<ProgressBar
progress={number('progress', 0, { min: 0, max: 1, step: 0.05 })}
width={number('width', 200, { min: 50, max: 500, step: 10 })}
/>
))

98
src/components/ProgressCircle/index.js

@ -0,0 +1,98 @@
// @flow
import React, { PureComponent } from 'react'
import styled, { css, keyframes } from 'styled-components'
import { colors } from 'styles/theme'
import Text from 'components/base/Text'
const STROKE_WIDTH = 10
type Props = {
progress: number,
size: number,
}
const animIndeterminate = keyframes`
0% {
}
50% {
}
100% {
}
`
const InnerCircle = styled.circle`
transform-origin: 50% 50%;
${p =>
p.progress === 0
? css`
animation: ${animIndeterminate} 3s cubic-bezier(0.61, 0.01, 0.39, 1.03) infinite;
`
: css`
transition: stroke-dashoffset 0.35s;
transform: rotate(-90deg);
`};
`
const Container = styled.div`
position: relative;
width: ${p => p.size}px;
height: ${p => p.size}px;
`
const TextContainer = styled.div`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
`
class ProgressCircle extends PureComponent<Props> {
render() {
const { size, progress } = this.props
const radius = size / 2
const normalizedRadius = radius - STROKE_WIDTH / 2
const circumference = normalizedRadius * 2 * Math.PI
const strokeDashoffset = circumference - progress * circumference
return (
<Container size={size}>
<TextContainer>
<Text ff="Museo Sans|Bold" color="graphite" fontSize={6}>
{`${Math.round(progress * 100)}%`}
</Text>
</TextContainer>
<svg height={size} width={size}>
<circle
stroke={colors.fog}
fill="transparent"
strokeWidth={STROKE_WIDTH}
style={{ strokeDashoffset }}
r={normalizedRadius}
cx={radius}
cy={radius}
/>
<InnerCircle
progress={progress}
stroke={colors.wallet}
fill="transparent"
strokeWidth={STROKE_WIDTH}
strokeDasharray={`${circumference} ${circumference}`}
style={{ strokeDashoffset }}
r={normalizedRadius}
cx={radius}
cy={radius}
/>
</svg>
</Container>
)
}
}
export default ProgressCircle

16
src/components/ProgressCircle/stories.js

@ -0,0 +1,16 @@
// @flow
import React from 'react'
import { storiesOf } from '@storybook/react'
import { number } from '@storybook/addon-knobs'
import ProgressCircle from 'components/ProgressCircle'
const stories = storiesOf('Components', module)
stories.add('ProgressCircle', () => (
<ProgressCircle
progress={number('progress', 0, { min: 0, max: 1, step: 0.01 })}
size={number('width', 150, { min: 50, max: 500, step: 10 })}
/>
))
Loading…
Cancel
Save