Merge pull request #2 from soyjavi/progress-bar

Progress bar
old
Javi Velasco 2015-07-07 09:32:43 +02:00
commit a786df1880
7 changed files with 237 additions and 0 deletions

View File

@ -34,6 +34,7 @@ INPUT_HEIGHT = (2 * SPACE)
BUTTON_HEIGHT = (2.5 * SPACE)
BUTTON_CIRCLE_HEIGHT = (2.75 * SPACE)
LOADING_HEIGHT = (1.5 * UNIT)
PROGRESS_BAR_HEIGHT = (SPACE / 4)
// -- Shadows
ZDEPTH_SHADOW_1 = 0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.24)

View File

@ -14,5 +14,6 @@ module.exports =
Loading : require "./loading"
Navigation : require "./navigation"
Ripple : require "./ripple"
ProgressBar : require "./progress_bar"
# -- Tools
Router : require "./router"

View File

@ -0,0 +1,69 @@
###
@todo
v2
- can set different sizes for circular progress
- maybe a multicolor indeterminate circular progress bar
- refactor vendor prefixes adding to a module
###
require './style'
module.exports = React.createClass
# -- Properties
propTypes:
buffer : React.PropTypes.number
className : React.PropTypes.string
max : React.PropTypes.number
min : React.PropTypes.number
mode : React.PropTypes.string
type : React.PropTypes.string
value : React.PropTypes.number
getDefaultProps: ->
buffer : 0
className : ''
max : 100
min : 0
mode : 'indeterminate'
type : 'linear'
value : 0
# -- Helper methods
calculateRatio: (value) ->
(value - @props.min) / (@props.max - @props.min)
# -- Render
render: ->
className = "#{@props.type} #{@props.className} #{@props.mode}"
<div data-component-progressbar role="progressbar"
className={className}
aria-valuenow={@props.value}
aria-valuemin={@props.min}
aria-valuemax={@props.max}>
{ if @props.type == 'circular' then @renderCircular() else @renderLinear() }
</div>
renderCircular: ->
style = transformDasharray(@calculateRatio(@props.value)) unless @props.mode == 'indeterminate'
<svg data-component-progressbar-circle>
<circle style={style} data-component-progressbar-circle-path cx="50" cy="50" r="45"/>
</svg>
renderLinear: ->
unless @props.mode == 'indeterminate'
bufferStyle = transformProgress(@calculateRatio(@props.buffer))
valueStyle = transformProgress(@calculateRatio(@props.value))
<div>
<span data-component-progressbar-buffer style={bufferStyle}></span>
<span data-component-progressbar-value style={valueStyle}></span>
</div>
# -- Private methods
transformDasharray = (ratio) ->
strokeDasharray: "#{2 * Math.PI * 45 * ratio}, 400"
transformProgress = (ratio) ->
WebkitTransform: "scaleX(#{ratio})"
MsTransform: "scaleX(#{ratio})"
transform: "scaleX(#{ratio})"

View File

@ -0,0 +1,27 @@
# Progress Bar
```javascript
var ProgressBar = require('react-toolbox/components/progress_bar');
// Circular indeterminate progress bar
<ProgressBar type="circular" mode="indeterminate" />
// Linear determinate progress bar with buffer
<ProgressBar type="linear" mode="determinate" value={83} buffer={90}/>
```
## Properties
| Name | Type | Default | Description|
| ------------- |:-------:|:--------------- |:---------- |
| **type** | String | `linear` | Type of the component, it can be *circular* or *linear*.|
| **mode** | String | `indeterminate` | Mode of the progress bar, it can be *determinate* or *indeterminate*.|
| **value** | Number | `0` | Value of the current progress.|
| **min** | Number | `0` | Minimum value permitted.|
| **max** | Number | `100` | Maximum value permitted.|
| **buffer** | Number | `0` | Value of a secondary progress bar useful for buffering.|
| **className** | String | `''` | Additional class name to provide custom styling.|
## Methods
This component has no methods.

View File

@ -0,0 +1,89 @@
@import '../constants.styl'
// -- NOTE: Parameters depend on the component SVG Markup too
CIRCLE_WRAPPER_WIDTH = 100
CIRCLE_RADIUS = 45
SCALE_RATIO = CIRCLE_RADIUS/20
[data-component-progressbar]
display : inline-block
&.linear
position : relative
height : PROGRESS_BAR_HEIGHT
width : 100%
background : darken(BACKGROUND, 7.5%)
overflow : hidden
[data-component-progressbar-value], [data-component-progressbar-buffer]
position : absolute
bottom : 0
left : 0
right : 0
top : 0
transform scaleX(0)
transform-origin left center
transition-duration ANIMATION_DURATION
transition-timing-function ANIMATION_EASE
[data-component-progressbar-value]
background-color : SECONDARY
[data-component-progressbar-buffer]
background-color : alpha(SECONDARY, 15%)
&.indeterminate [data-component-progressbar-value]
transform-origin center center
animation linear-indeterminate-bar 1s linear infinite
&.circular
position : relative
height : CIRCLE_WRAPPER_WIDTH * 1px
width : CIRCLE_WRAPPER_WIDTH * 1px
transform rotate(-90deg)
[data-component-progressbar-circle]
height : 100%
width : 100%
[data-component-progressbar-circle-path]
stroke-dasharray : 0, SCALE_RATIO * 200
stroke-dashoffset : 0
stroke-linecap : round
stroke-miterlimit : 20
stroke-width : 4
stroke : SECONDARY
fill : none
transition stroke-dasharray ANIMATION_DURATION ANIMATION_EASE
&.indeterminate
[data-component-progressbar-circle]
animation circular-indeterminate-bar-rotate 2s linear infinite
[data-component-progressbar-circle-path]
stroke-dasharray : SCALE_RATIO * 1, SCALE_RATIO * 200
stroke-dashoffset : 0
animation circular-indeterminate-bar-dash 1.5s ease-in-out infinite
@keyframes linear-indeterminate-bar
0%
transform translate(-50%) scaleX(0)
50%
transform translate(-0%) scaleX(0.3)
100%
transform translate(50%) scaleX(0)
@keyframes circular-indeterminate-bar-rotate
100%
transform : rotate(360deg)
@keyframes circular-indeterminate-bar-dash
0%
stroke-dasharray : SCALE_RATIO * 1, SCALE_RATIO * 200
stroke-dashoffset : SCALE_RATIO * 0
50%
stroke-dasharray : SCALE_RATIO * 89, SCALE_RATIO * 200
stroke-dashoffset : SCALE_RATIO * -35
100%
stroke-dasharray : SCALE_RATIO * 89, SCALE_RATIO * 200
stroke-dashoffset : SCALE_RATIO * -124

View File

@ -0,0 +1,48 @@
###
@todo
###
ProgressBar = require '../../components/progress_bar'
module.exports = React.createClass
# -- States & Properties
getInitialState: ->
progress: 0
buffer: 10
# -- Lifecycle
componentWillMount: ->
@simulateProgress()
# -- Simulate kind of a progress async function
simulateProgress: ->
setTimeout =>
if @state.progress < 100
@increaseProgress()
@increaseBuffer() if @state.progress > @state.buffer
else
@replaceState @getInitialState()
@simulateProgress()
, (Math.random() * 1 + 1) * 1000
increaseProgress: ->
@setState progress: Math.random() * 30 + @state.progress
increaseBuffer: ->
@setState buffer: Math.random() * (100 - @state.progress) + @state.progress
# -- Render
render: ->
<section>
<h2>Progress bars</h2>
<p>Determinate</p>
<ProgressBar mode="determinate" value={@state.progress} buffer={@state.buffer}/>
<p>Indeterminate...</p>
<ProgressBar mode="indeterminate"/>
<p>Circular</p>
<ProgressBar type="circular" mode="indeterminate"/>
</section>

View File

@ -7,6 +7,7 @@ Button = require './components/button'
Dialog = require './components/dialog'
Dropdown = require './components/dropdown'
Form = require './components/form'
Progress = require './components/progress'
# React = require('react/addons')
# TestUtils = React.addons.TestUtils
@ -30,6 +31,7 @@ Test = React.createClass
<Button />
<Dialog />
<Dropdown />
<Progress />
</app>
React.render <Test/>, document.body