ldx-widgets
Version:
widgets
153 lines (132 loc) • 5.08 kB
JavaScript
/*
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'})
*/
(function() {
var Animation, ConfirmSave, React, Spinner, div, easing;
React = require('react');
Animation = require('ainojs-animation');
easing = require('ainojs-easing');
Spinner = React.createFactory(require('./spinner'));
div = React.DOM.div;
ConfirmSave = React.createClass({
displayName: 'ConfirmSave',
getDefaultProps: function() {
return {
scaleCheckmark: 1,
animationDuration: 800,
vTranslateCheckmark: 0
};
},
getInitialState: function() {
return {
scale: .25
};
},
render: function() {
var checkClassName, content, ref, saveState, scale, scaleCheckmark, vTranslateCheckmark;
ref = this.props, saveState = ref.saveState, scaleCheckmark = ref.scaleCheckmark, vTranslateCheckmark = ref.vTranslateCheckmark;
scale = this.state.scale;
content = (saveState === 'pending' ? Spinner({
lines: 12,
length: 10,
width: 3,
radius: 8,
color: 'white'
}) : (checkClassName = 'confirm-check', saveState === 'failed' ? checkClassName += ' failed' : void 0, div({
className: checkClassName,
style: {
transform: "scale(" + scale + ")",
msTransform: "scale(" + scale + ")",
WebkitTransform: "scale(" + scale + ")"
}
})));
return 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: function() {
if (this.props.saveState === 'complete' || this.props.saveState === 'failed') {
return this.animateImmediately = true;
}
},
componentDidMount: function() {
if (this.animateImmediately) {
return this.animateCheck();
}
},
componentDidUpdate: function(prevProps) {
if (!(prevProps.saveState === 'pending' && (this.props.saveState === 'complete' || this.props.saveState === 'failed'))) {
return;
}
return this.animateCheck();
},
animateCheck: function() {
var animationDuration, ref, scale;
if ((ref = this.animation) != null ? ref.isAnimating() : void 0) {
this.animation.end();
}
scale = this.state.scale;
animationDuration = this.props.animationDuration;
return this.animation = new Animation({
duration: animationDuration,
easing: easing('easeOutElastic')
}).init({
scale: scale
}).on('frame', this.onFrame).on('complete', this.end).animateTo({
scale: 1
});
},
onFrame: function(e) {
if (this.isMounted()) {
return this.setState(e.values);
}
},
end: function() {
var base, base1, done, fail, ref, saveState;
ref = this.props, saveState = ref.saveState, done = ref.done, fail = ref.fail;
if (saveState === 'complete') {
return typeof (base = this.props).done === "function" ? base.done() : void 0;
} else {
return typeof (base1 = this.props).fail === "function" ? base1.fail() : void 0;
}
}
});
module.exports = ConfirmSave;
}).call(this);