UNPKG

ldx-widgets

Version:

widgets

135 lines (105 loc) 3.98 kB
### This component is intended to be used inside of a modal or popover, but could be used other places to confirm a save event was successful Confirm Save Props @props.saveState - string This can be either 'pending' or 'complete' or 'failed' - When 'pending', a spinner shows - When 'complete', a green check mark flashes before calling the done callback - When 'failed', a red x flashes before calling the fail callback @props.done - method This method will be called animationDuration ms after the saveState hits complete It will usually be a method that closes the popover or modal @props.fail - method This method will be called animationDuration ms after the saveState hits failed It will usually be a method that sets the parent's saveState back to null, which will remove this widget from the DOM @props.scaleCheckmark - default 1 percent to scale the confirm check and spinner @props.vTranslateCheckmark - default 0 number of pixels to move the checkmark up above the middle of the container @props.animationDuration - default 800 ms over which the check scalling takes place Tips for using this.. - It is absolutely positioned w/ all zeroes, to add to the top level of the render tree - Create a local 'saveState' state on your component, and default it to null - render like this: ConfirmSave { key: 'confirm' done: @close saveState: @state.saveState } if @state.saveState? This way, when you trigger the save, also call @setState({saveState: 'pending'}) Then pass a call back to the save action, which just calls @setState({saveState: 'complete'}) ### React = require 'react' Animation = require 'ainojs-animation' easing = require 'ainojs-easing' Spinner = React.createFactory(require './spinner') {div} = React.DOM ConfirmSave = React.createClass displayName: 'ConfirmSave' getDefaultProps: -> scaleCheckmark: 1 animationDuration: 800 vTranslateCheckmark: 0 getInitialState: -> scale: .25 render: -> {saveState, scaleCheckmark, vTranslateCheckmark} = @props {scale} = @state content = ( if saveState is 'pending' Spinner { lines: 12 length: 10 width: 3 radius: 8 color: 'white' } else checkClassName = 'confirm-check' checkClassName += ' failed' if saveState is 'failed' div { className: checkClassName style: transform: "scale(#{scale})" msTransform: "scale(#{scale})" WebkitTransform: "scale(#{scale})" } ) div { className: 'confirm-save-wrap' }, div { className: 'confirm-frame' style: transform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)" msTransform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)" WebkitTransform: "scale(#{scaleCheckmark}) translateY(#{vTranslateCheckmark}px)" }, content componentWillMount: -> # Handles the case when the saveState is never pending if @props.saveState is 'complete' or @props.saveState is 'failed' @animateImmediately = yes componentDidMount: -> @animateCheck() if @animateImmediately componentDidUpdate: (prevProps) -> return unless prevProps.saveState is 'pending' and (@props.saveState is 'complete' or @props.saveState is 'failed') @animateCheck() animateCheck: -> if @animation?.isAnimating() then @animation.end() {scale} = @state {animationDuration} = @props @animation = new Animation duration: animationDuration easing: easing('easeOutElastic') .init {scale} .on 'frame', @onFrame .on 'complete', @end .animateTo {scale: 1} onFrame: (e) -> if @isMounted() then @setState e.values end: -> {saveState, done, fail} = @props if saveState is 'complete' then @props.done?() else @props.fail?() module.exports = ConfirmSave