Skip to content

Commit

Permalink
- elevation support (credits to @jankalfus) -> fixed issue #41 and #43
Browse files Browse the repository at this point in the history
- killed componentWillReceiveProps() method -> fixed issue #58
- killed tab style (only 'float' available now) -> fixed #51
- fixed issue #65
  • Loading branch information
mastermoo committed Aug 23, 2016
1 parent b928dfe commit 30834f9
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 109 deletions.
140 changes: 61 additions & 79 deletions ActionButton.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component, PropTypes } from 'react';
import { StyleSheet, Text, View, Animated, Easing, TouchableOpacity, PixelRatio } from 'react-native';
import { StyleSheet, Text, View, Animated, TouchableOpacity } from 'react-native';
import ActionButtonItem from './ActionButtonItem';

const alignItemsMap = {
Expand All @@ -15,46 +15,16 @@ export default class ActionButton extends Component {

this.state = {
active: props.active,
btnOutRange: props.btnOutRange || props.buttonColor || 'rgba(0,0,0,1)',
btnOutRangeTxt: props.btnOutRangeTxt || props.buttonTextColor || 'rgba(255,255,255,1)',
anim: new Animated.Value(props.active ? 1 : 0),
}

this.anim = new Animated.Value(props.active ? 1 : 0);
this.timeout = null;
this.setPositionAndSizeByType();
}

componentWillUnmount() {
clearTimeout(this.timeout);
}

componentWillReceiveProps(nextProps) {
this.setState({
...nextProps
});
}

setPositionAndSizeByType() {
let position, offsetX, offsetY, size;

if (this.props.type == 'tab') {
position = 'center',
offsetX  = 10,
offsetY = 4,
size = 42;
} else {
position = 'right',
offsetX  = 30,
offsetY = 30,
size = 56;
}

this.state.position = this.props.position || position;
this.state.offsetX = this.props.offsetX  || offsetX ;
this.state.offsetY = this.props.offsetY  || offsetY;
this.state.size = this.props.size || size;
}


//////////////////////
// STYLESHEET GETTERS
Expand All @@ -69,20 +39,20 @@ export default class ActionButton extends Component {
}

getOrientation() {
return { alignItems: alignItemsMap[this.state.position] };
return { alignItems: alignItemsMap[this.props.position] };
}

getButtonSize() {
return {
width: this.state.size,
height: this.state.size,
width: this.props.size,
height: this.props.size,
}
}

getOffsetXY() {
return {
paddingHorizontal: this.state.offsetX,
paddingBottom: this.state.offsetY
paddingHorizontal: this.props.offsetX,
paddingBottom: this.props.offsetY
};
}

Expand All @@ -100,11 +70,13 @@ export default class ActionButton extends Component {
<View pointerEvents="box-none" style={styles.overlay}>
<Animated.View pointerEvents="none" style={[styles.overlay, {
backgroundColor: this.props.bgColor,
opacity: this.state.anim
opacity: this.anim
}]}>
{this.props.backdrop}
</Animated.View>
<View pointerEvents="box-none" style={this.getContainerStyles()}>
{this.state.active && this._renderTappableBackground()}

{this.props.children && this._renderActions()}
{this._renderButton()}
</View>
Expand All @@ -113,23 +85,25 @@ export default class ActionButton extends Component {
}

_renderButton() {
const buttonColorMax = this.props.btnOutRange ? this.props.btnOutRange : this.props.buttonColor;

const animatedViewStyle = [
styles.btn,
{
width: this.state.size,
height: this.state.size,
borderRadius: this.state.size / 2,
backgroundColor: this.state.anim.interpolate({
width: this.props.size,
height: this.props.size,
borderRadius: this.props.size / 2,
backgroundColor: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [this.props.buttonColor, this.state.btnOutRange]
outputRange: [this.props.buttonColor, buttonColorMax]
}),
transform: [{
scale: this.state.anim.interpolate({
scale: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [1, this.props.outRangeScale]
}),
}, {
rotate: this.state.anim.interpolate({
rotate: this.anim.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', this.props.degrees + 'deg']
})
Expand Down Expand Up @@ -158,13 +132,17 @@ export default class ActionButton extends Component {
}

_renderButtonIcon() {
if (this.props.icon) return this.props.icon
const { icon, btnOutRangeTxt, buttonTextColor } = this.props;

if (icon) return icon;

const buttonTextColorMax = btnOutRangeTxt ? btnOutRangeTxt : buttonTextColor;

return (
<Animated.Text style={[styles.btnText, {
color: this.state.anim.interpolate({
color: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [this.props.buttonTextColor, this.state.btnOutRangeTxt]
outputRange: [buttonTextColor, buttonTextColorMax]
})
}]}>
+
Expand All @@ -182,32 +160,42 @@ export default class ActionButton extends Component {
}

return (
<TouchableOpacity
<View
style={this.getActionsStyle()}
activeOpacity={1}
onPress={() => { this.reset() }}>
pointerEvents={'box-none'}
>
{actionButtons.map((ActionButton, index) => {
return (
<ActionButtonItem
key={index}
position={this.state.position}
position={this.props.position}
spacing={this.props.spacing}
anim={this.state.anim}
size={this.state.size}
btnColor={this.state.btnOutRange}
anim={this.anim}
parentSize={this.props.size}
size={this.props.size}
btnColor={this.props.btnOutRange}
{...ActionButton.props}
onPress={() => {
if (this.props.autoInactive){
this.timeout = setTimeout(() => {
this.reset();
}, 200);
this.timeout = setTimeout(this.reset.bind(this), 200);
}
ActionButton.props.onPress();
}}
/>
)
})}
</TouchableOpacity>
</View>
);
}

_renderTappableBackground() {
return (
<TouchableOpacity
activeOpacity={1}
style={styles.overlay}
pointerEvents={this.state.active ? 'auto' : 'box-none'}
onPress={this.reset.bind(this)}
/>
);
}

Expand All @@ -219,27 +207,17 @@ export default class ActionButton extends Component {
animateButton() {
if (this.state.active) return this.reset();

Animated.spring(this.state.anim, {
toValue: 1,
duration: 250,
}).start();
Animated.spring(this.anim, { toValue: 1 }).start();

this.setState({ active: true });
}

reset() {
if(this.props.onReset){
this.props.onReset();
}

Animated.spring(this.state.anim, {
toValue: 0,
duration: 250,
}).start();

setTimeout(() => {
this.setState({ active: false });
}, 250);
if (this.props.onReset) this.props.onReset();

Animated.spring(this.anim, { toValue: 0 }).start();

setTimeout(() => this.setState({ active: false }), 250);
}
}

Expand All @@ -248,7 +226,6 @@ ActionButton.Item = ActionButtonItem;
ActionButton.propTypes = {
active: PropTypes.bool,

type: PropTypes.oneOf(['float', 'tab']),
position: PropTypes.string,

hideShadow: PropTypes.bool,
Expand All @@ -257,7 +234,7 @@ ActionButton.propTypes = {
buttonColor: PropTypes.string,
buttonTextColor: PropTypes.string,

offsetX : PropTypes.number,
offsetX: PropTypes.number,
offsetY: PropTypes.number,
spacing: PropTypes.number,
size: PropTypes.number,
Expand All @@ -272,7 +249,6 @@ ActionButton.propTypes = {

ActionButton.defaultProps = {
active: false,
type: 'float',
bgColor: 'transparent',
buttonColor: 'rgba(0,0,0,1)',
buttonTextColor: 'rgba(255,255,255,1)',
Expand All @@ -281,7 +257,11 @@ ActionButton.defaultProps = {
autoInactive: true,
onPress: () => {},
backdrop: false,
degrees: 135
degrees: 135,
position: 'right',
offsetX: 30,
offsetY: 30,
size: 56,
};

const styles = StyleSheet.create({
Expand Down Expand Up @@ -316,6 +296,8 @@ const styles = StyleSheet.create({
},
shadowColor: '#444',
shadowRadius: 1,
elevation: 6,
marginBottom: 12,
},
actionsVertical: {
flex: 1,
Expand Down

0 comments on commit 30834f9

Please sign in to comment.