From 48e5b797402d95e203b6c7f97526df2bbfad4aa0 Mon Sep 17 00:00:00 2001 From: DeDuckProject Date: Tue, 27 Dec 2016 14:09:19 +0200 Subject: [PATCH 01/74] Fixed #120 (#121) * Changed to my styling * Added spaceBetween, actionTextStyle and actionTextViewStyle to ActionButtonItem props for higher customization. * Reverted back to original styling * Changed spaceBetween default to original * Update README.md Added spaceBetween to README * Fixed: Action button - only children in clickable, not entire button #120 --- ActionButton.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index e902c83..779be01 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -143,17 +143,17 @@ export default class ActionButton extends Component { return ( - - { this.props.onPress() if (this.props.children) this.animateButton() }}> + {this._renderButtonIcon()} - - + + ); } From 82dae8bc5c4e352dd60c49a3472260f29cf0917c Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Tue, 27 Dec 2016 13:10:44 +0100 Subject: [PATCH 02/74] 2.0.18 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5be2383..02e53ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.17", + "version": "2.0.18", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From f22ef35457a62c35eac52c9138714f764bfb32fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20S=C3=A9ra?= Date: Sat, 7 Jan 2017 12:39:21 +0100 Subject: [PATCH 03/74] Feature/active inactive button item (#124) * simple activation/deactivation solution * propTypes and default for "active" prop * fix missing import --- ActionButtonItem.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 5449589..4992be0 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, PropTypes } from 'react'; import { StyleSheet, Text, View, Animated, TouchableOpacity, Dimensions } from 'react-native'; const { width } = Dimensions.get('window'); @@ -9,7 +9,18 @@ const alignItemsMap = { } export default class ActionButtonItem extends Component { + static get defaultProps() { + return { + active: true, + }; + } + static get propTypes() { + return { + active: PropTypes.bool, + } + } + constructor(props) { super(props); this.state = { @@ -23,6 +34,10 @@ export default class ActionButtonItem extends Component { } render() { + if (!this.props.active) { + return null; + } + const translateXMap = { center: 0, left: (this.props.parentSize - this.props.size) / 2 - 8, From b9e58b961ae1abbd434c9e5e859748c01e380334 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 7 Jan 2017 12:53:40 +0100 Subject: [PATCH 04/74] 2.0.19 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02e53ac..bf4a5ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.18", + "version": "2.0.19", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 831a589c066debfad93f7ef26e3122a9a1d967c8 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 21 Jan 2017 16:37:59 +0100 Subject: [PATCH 05/74] issue #126 fixed --- ActionButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 779be01..69f7d3b 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -140,9 +140,9 @@ export default class ActionButton extends Component { } const actionButtonStyles = [ this.getActionButtonStyles(), combinedStyle, animatedViewStyle ] - + const shadowStyles = [styles.btnShadow, combinedStyle] return ( - + Date: Sat, 21 Jan 2017 16:38:17 +0100 Subject: [PATCH 06/74] 2.0.20 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf4a5ce..8056efe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.19", + "version": "2.0.20", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 65e0dfeca73f4206e29a0ec38b76772a101a376d Mon Sep 17 00:00:00 2001 From: Deepak Sisodiya Date: Mon, 6 Feb 2017 15:24:00 +0530 Subject: [PATCH 07/74] RN ~0.39.0 fix for ActionButton children not rendering --- ActionButtonItem.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 4992be0..f7d038b 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -73,7 +73,6 @@ export default class ActionButtonItem extends Component { ]} > From 9211d346a8a4ab438d31133fecf23795714eac18 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 11 Feb 2017 11:39:38 +0100 Subject: [PATCH 08/74] 2.0.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8056efe..25a58c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.20", + "version": "2.0.21", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From bba67761614d65e78f64b002acd9b00f894dd922 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 11 Feb 2017 12:17:10 +0100 Subject: [PATCH 09/74] fixed #132 --- ActionButtonItem.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index f7d038b..5834311 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -39,9 +39,9 @@ export default class ActionButtonItem extends Component { } const translateXMap = { - center: 0, + center: this.props.parentSize/2, left: (this.props.parentSize - this.props.size) / 2 - 8, - right: -(this.props.parentSize - this.props.size) / 2 + 8, + right: this.props.parentSize + 12 - ((this.props.parentSize - this.props.size) / 2), } const translateX = translateXMap[this.props.position]; From 38302e7a797257c6fe9930d305637ba535dc6af2 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 11 Feb 2017 12:17:25 +0100 Subject: [PATCH 10/74] 2.0.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25a58c9..9ec995f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.21", + "version": "2.0.22", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 9ca849f667d758e00dc1b7152d57a9dcd2c26535 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 25 Feb 2017 17:52:43 +0100 Subject: [PATCH 11/74] positioning code rewritten. should fix #136 and #138 --- ActionButton.js | 208 ++++++++++++++++---------------------------- ActionButtonItem.js | 189 +++++++++++++++------------------------- README.md | 12 +-- shared.js | 29 ++++++ 4 files changed, 177 insertions(+), 261 deletions(-) create mode 100644 shared.js diff --git a/ActionButton.js b/ActionButton.js index 69f7d3b..260ab17 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,17 +1,10 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity, Platform } from 'react-native'; +import { StyleSheet, Text, View, Animated, TouchableOpacity } from 'react-native'; import ActionButtonItem from './ActionButtonItem'; +import { SHADOW_SIZE, shadowStyle, alignItemsMap, positionMap } from './shared'; -const alignItemsMap = { - "center" : "center", - "left" : "flex-start", - "right" : "flex-end" -} - -const shadowHeight = 12; export default class ActionButton extends Component { - constructor(props) { super(props); @@ -32,45 +25,17 @@ export default class ActionButton extends Component { // STYLESHEET GETTERS ////////////////////// - getContainerStyles() { - return [this.getOverlayStyles(), this.getOrientation(), this.getOffsetXY()]; - } - - getActionButtonStyles() { - const actionButtonStyles = [styles.actionBarItem, this.getButtonSize()]; - return actionButtonStyles; - } - getOrientation() { return { alignItems: alignItemsMap[this.props.position] }; } - getButtonSize() { - return { - width: this.props.size + 16, - height: this.props.size + shadowHeight, - } - } - getOffsetXY() { return { - paddingHorizontal: this.props.offsetX - 8, - paddingBottom: this.props.verticalOrientation === 'up' ? this.props.offsetY : 0, - paddingTop: this.props.verticalOrientation === 'down' ? this.props.offsetY : 0 + paddingHorizontal: this.props.offsetX, + paddingVertical: this.props.offsetY }; } - getActionsStyle() { - return [ - styles.actionsVertical, - this.getOrientation(), - { - flexDirection: 'column', - justifyContent: this.props.verticalOrientation === 'up' ? 'flex-end' : 'flex-start' - }, - ]; - } - getOverlayStyles() { return [ styles.overlay, @@ -94,12 +59,12 @@ export default class ActionButton extends Component { }]}> {this.props.backdrop} - + {(this.state.active && !this.props.backgroundTappable) && this._renderTappableBackground()} {this.props.verticalOrientation === 'up' && this.props.children && this._renderActions()} - {this._renderButton()} + {this._renderMainButton()} {this.props.verticalOrientation === 'down' && this.props.children && this._renderActions()} @@ -107,69 +72,66 @@ export default class ActionButton extends Component { ); } - _renderButton() { - const buttonColorMax = this.props.btnOutRange ? this.props.btnOutRange : this.props.buttonColor; - - const animatedViewStyle = [ - styles.btn, - { - backgroundColor: this.anim.interpolate({ + _renderMainButton() { + const animatedViewStyle = { + backgroundColor: this.anim.interpolate({ + inputRange: [0, 1], + outputRange: [this.props.buttonColor, (this.props.btnOutRange || this.props.buttonColor)] + }), + transform: [{ + scale: this.anim.interpolate({ inputRange: [0, 1], - outputRange: [this.props.buttonColor, buttonColorMax] + outputRange: [1, this.props.outRangeScale] }), - transform: [{ - scale: this.anim.interpolate({ - inputRange: [0, 1], - outputRange: [1, this.props.outRangeScale] - }), - }, { - rotate: this.anim.interpolate({ - inputRange: [0, 1], - outputRange: ['0deg', this.props.degrees + 'deg'] - }) - }], - }, - ]; - - const combinedStyle = { + }, { + rotate: this.anim.interpolate({ + inputRange: [0, 1], + outputRange: ['0deg', this.props.degrees + 'deg'] + }) + }], + }; + + const touchableStyle = { + width: this.props.size, + height: this.props.size, + margin: SHADOW_SIZE, + borderRadius: this.props.size / 2, + ...positionMap(this.props.position, this.props.verticalOrientation) + } + + const buttonStyle = { width: this.props.size, height: this.props.size, borderRadius: this.props.size / 2, - marginBottom: shadowHeight, - backgroundColor: this.props.buttonColor + alignItems: 'center', + justifyContent: 'center', } - const actionButtonStyles = [ this.getActionButtonStyles(), combinedStyle, animatedViewStyle ] - const shadowStyles = [styles.btnShadow, combinedStyle] return ( - - { - this.props.onPress() - if (this.props.children) this.animateButton() - }}> - - {this._renderButtonIcon()} - - - + { + this.props.onPress() + if (this.props.children) this.animateButton() + }}> + + {this._renderButtonIcon()} + + ); } _renderButtonIcon() { const { icon, btnOutRangeTxt, buttonTextColor } = this.props; - if (icon) return icon; - const buttonTextColorMax = btnOutRangeTxt ? btnOutRangeTxt : buttonTextColor; - return ( + @@ -178,38 +140,38 @@ export default class ActionButton extends Component { } _renderActions() { + const { children, verticalOrientation } = this.props; + if (!this.state.active) return null; - let actionButtons = this.props.children + const actionButtons = !Array.isArray(children) ? [children] : children; - if (!Array.isArray(this.props.children)) { - actionButtons = [this.props.children] - } + const actionStyle = { + flex: 1, + justifyContent: verticalOrientation === 'up' ? 'flex-end' : 'flex-start', + }; return ( - - {actionButtons.map((ActionButton, index) => { - return ( -  { - if (this.props.autoInactive){ - this.timeout = setTimeout(this.reset.bind(this), 200); - } - ActionButton.props.onPress(); - }} - /> - ) - })} - + + {actionButtons.map((ActionButton, idx) => ( +  { + if (this.props.autoInactive){ + this.timeout = setTimeout(this.reset.bind(this), 200); + } + ActionButton.props.onPress(); + }} + /> + ))} + ); } @@ -309,32 +271,10 @@ const styles = StyleSheet.create({ top: 0, backgroundColor: 'transparent', }, - actionBarItem: { - alignItems: 'center', - justifyContent: 'center', - backgroundColor: 'transparent', - marginBottom: 12, - }, - btn: { - justifyContent: 'center', - alignItems: 'center', - }, btnText: { marginTop: -4, fontSize: 24, backgroundColor: 'transparent', position: 'relative', }, - btnShadow: { - shadowOpacity: 0.3, - shadowOffset: { - width: 0, height: 8, - }, - shadowColor: '#000', - shadowRadius: 4, - elevation: 8, - }, - actionsVertical: { - flex: 1, - } }); diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 5834311..88c4fab 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,17 +1,12 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity, Dimensions } from 'react-native'; -const { width } = Dimensions.get('window'); - -const alignItemsMap = { - center: "center", - left: "flex-start", - right: "flex-end" -} +import { StyleSheet, Text, View, Animated, TouchableOpacity } from 'react-native'; +import { SHADOW_SIZE, shadowStyle, alignItemsMap, positionMap } from './shared'; export default class ActionButtonItem extends Component { static get defaultProps() { return { active: true, + spaceBetween: 15 }; } @@ -20,150 +15,102 @@ export default class ActionButtonItem extends Component { active: PropTypes.bool, } } - - constructor(props) { - super(props); - this.state = { - spaceBetween: this.props.spaceBetween || 15, - alignItems: alignItemsMap[this.props.position] - }; - - if (!props.children || Array.isArray(props.children)) { - throw new Error("ActionButtonItem must have a Child component."); - } - } render() { - if (!this.props.active) { - return null; - } - - const translateXMap = { - center: this.props.parentSize/2, - left: (this.props.parentSize - this.props.size) / 2 - 8, - right: this.props.parentSize + 12 - ((this.props.parentSize - this.props.size) / 2), - } + const { + active, parentSize, size, anim, position, verticalOrientation, + activeOpacity, onPress, hideShadow, style, buttonColor, btnColor, + actionButtons, idx, spacing, children + } = this.props; + + if (!active) return null; + + const animatedViewStyle = { + height: size, + margin: SHADOW_SIZE, + opacity: anim, + transform: [ + { + translateY: anim.interpolate({ + inputRange: [0, 1], + outputRange: [verticalOrientation === 'down' ? -40 : 40, 0] + }), + } + ], + ...positionMap(position, verticalOrientation), + }; - const translateX = translateXMap[this.props.position]; - const margin = (this.props.spacing < 12) ? 0 : (this.props.spacing - 12); + if (verticalOrientation === 'up') + animatedViewStyle.top = SHADOW_SIZE + (SHADOW_SIZE*2 - spacing) * (actionButtons-idx); + + if (verticalOrientation === 'down') + animatedViewStyle.top = -SHADOW_SIZE - (SHADOW_SIZE*2 - spacing) * (idx+1); return ( - - + + - {this.props.children} + {children} - {this.props.title && ( - - - {this.props.title} - - - )} + {this._renderTitle()} ); } - getTextStyles() { - // to align the center of the label with the center of the button, - // offset = (half the size of the btn) - (half the size of the label) - let directionOffset = this.props.verticalOrientation === 'down' ? -12 : 0 - let offsetTop = this.props.size >= 28 ? (this.props.size / 2) - 14 + directionOffset : 0; - - let positionStyles = { - right: this.props.size + this.state.spaceBetween + 8, - top: offsetTop - } + _renderTitle() { + const { title, textContainerStyle, hideShadow, activeOpacity, onPress, textStyle } = this.props; - let bgStyle = { backgroundColor : 'white' }; + if (!title) return null; - if (this.props.titleBgColor) bgStyle = { - backgroundColor:this.props.titleBgColor - } + return ( + + {title} + + ); + } - if (this.props.position == 'left') positionStyles = { - left: this.props.size + this.state.spaceBetween + 8, - top: offsetTop - } + getTextStyles() { + const { size, position, spaceBetween, textContainerStyle, hideShadow } = this.props; + const offsetTop = Math.max((size / 2) - (TEXT_HEIGHT/2), 0); + const textMap = { + left: 'left', + center: 'right', + right: 'right' + }; - if (this.props.position == 'center') positionStyles = { - right: this.props.size/2 + width/2 + this.state.spaceBetween, - top: offsetTop - } + const positionStyles = { top: offsetTop }; + positionStyles[textMap[position]] = size + spaceBetween; - return [styles.actionTextView, positionStyles, bgStyle]; + return [styles.textContainer, positionStyles, textContainerStyle, !hideShadow && shadowStyle]; } } +const TEXT_HEIGHT = 26; + const styles = StyleSheet.create({ - actionButtonWrap: { - width - }, - actionButton: { - justifyContent: 'center', - alignItems: 'center', - flexDirection: 'row', - }, - shadow: { - shadowOpacity: 0.3, - shadowOffset: { - width: 0, height: 8, - }, - shadowColor: '#000', - shadowRadius: 4, - elevation: 6, - }, - actionTextView: { + textContainer: { position: 'absolute', paddingVertical: 4, paddingHorizontal: 10, borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: '#eee', + backgroundColor: 'white', + height: TEXT_HEIGHT }, - actionText: { + text: { flex: 1, fontSize: 14, + color: '#444', } }); diff --git a/README.md b/README.md index 0c35e20..2326b8e 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ class App extends Component { render() { return ( - {/*Rest of App come ABOVE the action button component!*/} + {/* Rest of the app comes ABOVE the action button component !*/} console.log("notes tapped!")}> @@ -93,8 +93,8 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | bgColor | string | "transparent" | background color when ActionButtons are visible | buttonColor | string | "rgba(0,0,0,1)" | background color of the +Button **(must be rgba value!)** | spacing | number | 20 | spacing between the `ActionButton.Item`s -| offsetX | number | 10 / 30 | offset from the left/right side of the screen for `left`/`right` position respectively -| offsetY | number | 4 / 30 | offset from the bottom/top of the screen for `up`/`down` verticalOrientation respectively +| offsetX | number | 30 | offset from the left/right side of the screen +| offsetY | number | 30 | offset from the bottom/top of the screen | btnOutRange | string | props.buttonColor | button background color to animate to | outRangeScale | number | 1 | changes size of button during animation | onPress | function | null | fires, when ActionButton is tapped @@ -111,11 +111,11 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 ##### ActionButton.Item: | Property | Type | Default | Description | | ------------- |:-------------:|:------------: | ----------- | -| title | string | undefined | the title shown next to the button, not shown when empty +| title | string | undefined | the title shown next to the button. When `undefined` the title is not hidden | onPress | func | null | **required** function, triggers when a button is tapped | buttonColor | string | same as + button | background color of the Button -| titleColor | string | "#444" | color of title -| titleBgColor | string | "white" | background color of title +| titleColor | string | "#444" | color of title, *removed* in v2.5. use `textStyle` instead +| titleBgColor | string | "white" | background color of title, *removed* in v2.5. use `textStyle` instead | textContainerStyle | style | null | use this to set the textstyle of the button's item text container | textStyle | style | null | use this to set the textstyle of the button's item text | spaceBetween | number | 15 | use this to set the space between the Button and the text container diff --git a/shared.js b/shared.js new file mode 100644 index 0000000..ebdafd4 --- /dev/null +++ b/shared.js @@ -0,0 +1,29 @@ +export const SHADOW_SIZE = 20; + +export const shadowStyle = { + shadowOpacity: 0.3, + shadowOffset: { + width: 0, height: (SHADOW_SIZE/3), + }, + shadowColor: '#000', + shadowRadius: 4, + elevation: (SHADOW_SIZE/3), +}; + +export const alignItemsMap = { + center: "center", + left: "flex-start", + right: "flex-end" +}; + +export const positionMap = (position, orientation) => { + const topOrBottom = orientation === 'up' ? 'bottom' : 'top'; + + const style = { + [topOrBottom]: -SHADOW_SIZE + }; + + if (position !== 'center') style[position] = -SHADOW_SIZE; + + return style; +}; \ No newline at end of file From 1ca05ec273ee7fc8707fbce2a977126f7b7bb42d Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 25 Feb 2017 17:57:54 +0100 Subject: [PATCH 12/74] bump npm version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ec995f..c58a310 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.0.22", + "version": "2.5.0", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From f3b36ee7521d2a9a6c4ed2d0bc6e596e0a50b097 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sun, 26 Feb 2017 11:21:50 +0100 Subject: [PATCH 13/74] - should resolve shadow calculation warning 492934th time - #139 maybe fixed, probably not - shadow size reduced to 10pt to minimize overlapping issue on android --- ActionButton.js | 22 +++++++++++++++------- ActionButtonItem.js | 10 ++++++++-- README.md | 5 +++++ shared.js | 10 +++++----- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 260ab17..fca1086 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -74,10 +74,6 @@ export default class ActionButton extends Component { _renderMainButton() { const animatedViewStyle = { - backgroundColor: this.anim.interpolate({ - inputRange: [0, 1], - outputRange: [this.props.buttonColor, (this.props.btnOutRange || this.props.buttonColor)] - }), transform: [{ scale: this.anim.interpolate({ inputRange: [0, 1], @@ -99,6 +95,16 @@ export default class ActionButton extends Component { ...positionMap(this.props.position, this.props.verticalOrientation) } + const wrapperStyle = { + backgroundColor: this.anim.interpolate({ + inputRange: [0, 1], + outputRange: [this.props.buttonColor, (this.props.btnOutRange || this.props.buttonColor)] + }), + width: this.props.size, + height: this.props.size, + borderRadius: this.props.size / 2, + } + const buttonStyle = { width: this.props.size, height: this.props.size, @@ -109,15 +115,17 @@ export default class ActionButton extends Component { return ( { this.props.onPress() if (this.props.children) this.animateButton() }}> - - {this._renderButtonIcon()} + + + {this._renderButtonIcon()} + ); diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 88c4fab..84ce6ce 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -26,6 +26,7 @@ export default class ActionButtonItem extends Component { if (!active) return null; const animatedViewStyle = { + backgroundColor: 'transparent', height: size, margin: SHADOW_SIZE, opacity: anim, @@ -37,7 +38,6 @@ export default class ActionButtonItem extends Component { }), } ], - ...positionMap(position, verticalOrientation), }; if (verticalOrientation === 'up') @@ -45,10 +45,16 @@ export default class ActionButtonItem extends Component { if (verticalOrientation === 'down') animatedViewStyle.top = -SHADOW_SIZE - (SHADOW_SIZE*2 - spacing) * (idx+1); + + if (position !== 'center') + animatedViewStyle[position] = -SHADOW_SIZE + (parentSize-size)/2; return ( - + Date: Sun, 26 Feb 2017 11:22:13 +0100 Subject: [PATCH 14/74] 2.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c58a310..581562f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.5.0", + "version": "2.5.1", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 698b5bf373a35a81401e139534fcfe2f63da0144 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sun, 26 Feb 2017 18:16:14 +0100 Subject: [PATCH 15/74] =?UTF-8?q?-=20fixed=20#140=20-=20added=20MD=20Rippl?= =?UTF-8?q?e=20Effect=20on=20Android=20->=20fixed=20#34=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ActionButton.js | 53 +++++++++----------- ActionButtonItem.js | 117 ++++++++++++++++++++++---------------------- README.md | 2 - package.json | 2 +- shared.js | 19 +++---- 5 files changed, 88 insertions(+), 105 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index fca1086..64a7e53 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,8 +1,7 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity } from 'react-native'; +import { StyleSheet, Text, View, Animated, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; import ActionButtonItem from './ActionButtonItem'; -import { SHADOW_SIZE, shadowStyle, alignItemsMap, positionMap } from './shared'; - +import { shadowStyle, alignItemsMap, Touchable, isAndroid } from './shared'; export default class ActionButton extends Component { constructor(props) { @@ -31,7 +30,7 @@ export default class ActionButton extends Component { getOffsetXY() { return { - paddingHorizontal: this.props.offsetX, + // paddingHorizontal: this.props.offsetX, paddingVertical: this.props.offsetY }; } @@ -87,14 +86,6 @@ export default class ActionButton extends Component { }], }; - const touchableStyle = { - width: this.props.size, - height: this.props.size, - margin: SHADOW_SIZE, - borderRadius: this.props.size / 2, - ...positionMap(this.props.position, this.props.verticalOrientation) - } - const wrapperStyle = { backgroundColor: this.anim.interpolate({ inputRange: [0, 1], @@ -114,20 +105,22 @@ export default class ActionButton extends Component { } return ( - { - this.props.onPress() - if (this.props.children) this.animateButton() - }}> - - - {this._renderButtonIcon()} + + { + this.props.onPress() + if (this.props.children) this.animateButton() + }}> + + + {this._renderButtonIcon()} + - - + + ); } @@ -156,19 +149,20 @@ export default class ActionButton extends Component { const actionStyle = { flex: 1, + alignSelf: 'stretch', + // backgroundColor: 'purple', justifyContent: verticalOrientation === 'up' ? 'flex-end' : 'flex-start', + paddingTop: this.props.verticalOrientation === 'down' ? this.props.spacing : 0 }; return ( - + {actionButtons.map((ActionButton, idx) => (  { @@ -261,7 +255,7 @@ ActionButton.defaultProps = { autoInactive: true, onPress: () => {}, backdrop: false, - degrees: 135, + degrees: 45, position: 'right', offsetX: 30, offsetY: 30, @@ -283,6 +277,5 @@ const styles = StyleSheet.create({ marginTop: -4, fontSize: 24, backgroundColor: 'transparent', - position: 'relative', }, }); diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 84ce6ce..07b238e 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,6 +1,11 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity } from 'react-native'; -import { SHADOW_SIZE, shadowStyle, alignItemsMap, positionMap } from './shared'; +import { StyleSheet, Text, View, Animated, + TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions } from 'react-native'; +import { shadowStyle, alignItemsMap, Touchable, isAndroid } from './shared'; + +const { width: WIDTH } = Dimensions.get('window'); +const SHADOW_SPACE = 10; +const TextTouchable = isAndroid ? TouchableNativeFeedback : TouchableWithoutFeedback; export default class ActionButtonItem extends Component { static get defaultProps() { @@ -17,22 +22,21 @@ export default class ActionButtonItem extends Component { } render() { - const { - active, parentSize, size, anim, position, verticalOrientation, - activeOpacity, onPress, hideShadow, style, buttonColor, btnColor, - actionButtons, idx, spacing, children - } = this.props; + const { size, position, verticalOrientation, hideShadow, spacing } = this.props; - if (!active) return null; + if (!this.props.active) return null; const animatedViewStyle = { - backgroundColor: 'transparent', - height: size, - margin: SHADOW_SIZE, - opacity: anim, + height: size + SHADOW_SPACE + spacing, + marginBottom: -SHADOW_SPACE, + paddingHorizontal: this.props.offsetX, + alignItems: alignItemsMap[position], + + // backgroundColor: this.props.buttonColor, + opacity: this.props.anim, transform: [ { - translateY: anim.interpolate({ + translateY: this.props.anim.interpolate({ inputRange: [0, 1], outputRange: [verticalOrientation === 'down' ? -40 : 40, 0] }), @@ -40,74 +44,69 @@ export default class ActionButtonItem extends Component { ], }; - if (verticalOrientation === 'up') - animatedViewStyle.top = SHADOW_SIZE + (SHADOW_SIZE*2 - spacing) * (actionButtons-idx); - - if (verticalOrientation === 'down') - animatedViewStyle.top = -SHADOW_SIZE - (SHADOW_SIZE*2 - spacing) * (idx+1); - - if (position !== 'center') - animatedViewStyle[position] = -SHADOW_SIZE + (parentSize-size)/2; + const buttonStyle = { + justifyContent: 'center', + alignItems: 'center', + width: size, + height: size, + borderRadius: size / 2, + backgroundColor: this.props.buttonColor || this.props.btnColor, + } + + if (position !== 'center') buttonStyle[position] = (this.props.parentSize-size)/2; return ( - + - {children} + {this.props.children} - + {this._renderTitle()} ); } _renderTitle() { - const { title, textContainerStyle, hideShadow, activeOpacity, onPress, textStyle } = this.props; - - if (!title) return null; - - return ( - - {title} - - ); - } + if (!this.props.title) return null; - getTextStyles() { - const { size, position, spaceBetween, textContainerStyle, hideShadow } = this.props; + const { textContainerStyle, hideShadow, offsetX, parentSize, size, position, spaceBetween } = this.props; const offsetTop = Math.max((size / 2) - (TEXT_HEIGHT/2), 0); - const textMap = { - left: 'left', - center: 'right', - right: 'right' - }; - const positionStyles = { top: offsetTop }; - positionStyles[textMap[position]] = size + spaceBetween; - return [styles.textContainer, positionStyles, textContainerStyle, !hideShadow && shadowStyle]; + if (position !== 'center') { + positionStyles[position] = offsetX + (parentSize-size)/2 + size + spaceBetween; + } else { + positionStyles.right = WIDTH/2 + size/2 + spaceBetween; + } + + const textStyles = [styles.textContainer, positionStyles, textContainerStyle, !hideShadow && shadowStyle]; + + return ( + + + {this.props.title} + + + ); } } -const TEXT_HEIGHT = 26; +const TEXT_HEIGHT = 22; const styles = StyleSheet.create({ textContainer: { position: 'absolute', - paddingVertical: 4, - paddingHorizontal: 10, + paddingVertical: (isAndroid ? 2 : 3), + paddingHorizontal: 8, borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, borderColor: '#eee', @@ -116,7 +115,7 @@ const styles = StyleSheet.create({ }, text: { flex: 1, - fontSize: 14, + fontSize: 12, color: '#444', } }); diff --git a/README.md b/README.md index ee998bd..85e1f45 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ customizable multi-action-button component for react-native ![react-native-action-button demo](http://i.giphy.com/xTcnSOtuet39cM46s0.gif) ### Known Issues -- Some people get a "shadow calculation warning". - Doesn't Work While Android Debugging. See issue [#79](https://github.com/mastermoo/react-native-action-button/issues/79). -- ActionButtons can get cropped on Android, when `spacing` is not set high enough. ### Installation ```bash diff --git a/package.json b/package.json index 581562f..d6cda72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.5.1", + "version": "2.6.0", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { diff --git a/shared.js b/shared.js index 1797ac7..708f51f 100644 --- a/shared.js +++ b/shared.js @@ -1,4 +1,4 @@ -export const SHADOW_SIZE = 10; +import { Platform, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; export const shadowStyle = { shadowOpacity: 0.35, @@ -11,19 +11,12 @@ export const shadowStyle = { }; export const alignItemsMap = { - center: "center", - left: "flex-start", - right: "flex-end" + center: 'center', + left: 'flex-start', + right: 'flex-end' }; -export const positionMap = (position, orientation) => { - const topOrBottom = orientation === 'up' ? 'bottom' : 'top'; - const style = { - [topOrBottom]: -SHADOW_SIZE - }; +export const Touchable = Platform.OS === 'ios' ? TouchableOpacity : TouchableNativeFeedback; - if (position !== 'center') style[position] = -SHADOW_SIZE; - - return style; -}; \ No newline at end of file +export const isAndroid = Platform.OS === 'android'; \ No newline at end of file From 4f400b7abea6d0dde82bbea193f385b65d7d7a97 Mon Sep 17 00:00:00 2001 From: HABIB ZAHMANI Samir Date: Mon, 27 Feb 2017 11:23:29 +0100 Subject: [PATCH 16/74] Fix for Platform < 21 --- ActionButton.js | 4 ++-- ActionButtonItem.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 64a7e53..ba8e38a 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,5 +1,5 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; +import { StyleSheet, Text, View, Animated, TouchableOpacity, TouchableNativeFeedback, Platform } from 'react-native'; import ActionButtonItem from './ActionButtonItem'; import { shadowStyle, alignItemsMap, Touchable, isAndroid } from './shared'; @@ -107,7 +107,7 @@ export default class ActionButton extends Component { return ( = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} activeOpacity={0.85} onLongPress={this.props.onLongPress} onPress={() => { diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 07b238e..f55f97b 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,6 +1,6 @@ import React, { Component, PropTypes } from 'react'; import { StyleSheet, Text, View, Animated, - TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions } from 'react-native'; + TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions, Platform } from 'react-native'; import { shadowStyle, alignItemsMap, Touchable, isAndroid } from './shared'; const { width: WIDTH } = Dimensions.get('window'); @@ -58,7 +58,7 @@ export default class ActionButtonItem extends Component { return ( = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} activeOpacity={this.props.activeOpacity || 0.85} onPress={this.props.onPress}> = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} activeOpacity={this.props.activeOpacity || 0.85} onPress={this.props.onPress}> From 0d01ab9186eaae246fe0d3c7e19b1b32959d8b12 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Wed, 1 Mar 2017 00:38:26 +0100 Subject: [PATCH 17/74] 2.6.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d6cda72..6a451cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.0", + "version": "2.6.1", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 7e355c0e19d9870e508e8a0c6689c3b0408c8af9 Mon Sep 17 00:00:00 2001 From: Kaishley Lingachetti Date: Thu, 2 Mar 2017 09:36:01 +0400 Subject: [PATCH 18/74] Fix iOS issue created after v6.2.1 --- ActionButton.js | 11 ++++++++++- ActionButtonItem.js | 22 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index ba8e38a..fba127b 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -104,10 +104,19 @@ export default class ActionButton extends Component { justifyContent: 'center', } + var touchableBackground; + if (isAndroid) { + if (Platform['Version'] >= 21) { + touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); + } else { + touchableBackground = TouchableNativeFeedback.SelectableBackground(); + } + } + return ( = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} + background={touchableBackground} activeOpacity={0.85} onLongPress={this.props.onLongPress} onPress={() => { diff --git a/ActionButtonItem.js b/ActionButtonItem.js index f55f97b..a88b56e 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -55,10 +55,19 @@ export default class ActionButtonItem extends Component { if (position !== 'center') buttonStyle[position] = (this.props.parentSize-size)/2; + var touchableBackground; + if (isAndroid) { + if (Platform['Version'] >= 21) { + touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); + } else { + touchableBackground = TouchableNativeFeedback.SelectableBackground(); + } + } + return ( = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} + background={touchableBackground} activeOpacity={this.props.activeOpacity || 0.85} onPress={this.props.onPress}> = 21) { + touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); + } else { + touchableBackground = TouchableNativeFeedback.SelectableBackground(); + } + } + return ( = 21) ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground()} + background={touchableBackground} activeOpacity={this.props.activeOpacity || 0.85} onPress={this.props.onPress}> From 51732ae4a878f14533d65aa12e5dff32483ffb74 Mon Sep 17 00:00:00 2001 From: Kaishley Lingachetti Date: Thu, 2 Mar 2017 15:21:26 +0400 Subject: [PATCH 19/74] Refactor common code. --- ActionButton.js | 11 +---------- ActionButtonItem.js | 20 +------------------- shared.js | 4 +++- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index fba127b..bad30c1 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,7 +1,7 @@ import React, { Component, PropTypes } from 'react'; import { StyleSheet, Text, View, Animated, TouchableOpacity, TouchableNativeFeedback, Platform } from 'react-native'; import ActionButtonItem from './ActionButtonItem'; -import { shadowStyle, alignItemsMap, Touchable, isAndroid } from './shared'; +import { shadowStyle, alignItemsMap, Touchable, isAndroid, touchableBackground } from './shared'; export default class ActionButton extends Component { constructor(props) { @@ -104,15 +104,6 @@ export default class ActionButton extends Component { justifyContent: 'center', } - var touchableBackground; - if (isAndroid) { - if (Platform['Version'] >= 21) { - touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); - } else { - touchableBackground = TouchableNativeFeedback.SelectableBackground(); - } - } - return ( = 21) { - touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); - } else { - touchableBackground = TouchableNativeFeedback.SelectableBackground(); - } - } - return ( = 21) { - touchableBackground = TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)'); - } else { - touchableBackground = TouchableNativeFeedback.SelectableBackground(); - } - } - return ( = 21 ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground() : undefined; \ No newline at end of file From 50ec4a139de9456b74b29cb98c3bb6f2051c7516 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Thu, 2 Mar 2017 12:28:29 +0100 Subject: [PATCH 20/74] 2.6.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a451cf..6d17f63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.1", + "version": "2.6.2", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 5831c7ecc1b7cdce156a62452c2270c33b02dd1c Mon Sep 17 00:00:00 2001 From: Fabrizio Moscon Date: Sun, 5 Mar 2017 15:35:55 +0000 Subject: [PATCH 21/74] Add prop useNativeFeedback - introduce props useNativeFeedback default to true - document props activeOpacity and make a constant for the default value - convert tabs into spaces in shared.js to be consistent with the other files --- ActionButton.js | 16 +++++++++++----- ActionButtonItem.js | 19 +++++++++++++------ README.md | 4 ++++ shared.js | 38 ++++++++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index bad30c1..7a71c74 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,7 +1,7 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity, TouchableNativeFeedback, Platform } from 'react-native'; +import { StyleSheet, Text, View, Animated, TouchableOpacity, Platform } from 'react-native'; import ActionButtonItem from './ActionButtonItem'; -import { shadowStyle, alignItemsMap, Touchable, isAndroid, touchableBackground } from './shared'; +import { shadowStyle, alignItemsMap, getTouchableComponent, isAndroid, touchableBackground, DEFAULT_ACTIVE_OPACITY } from './shared'; export default class ActionButton extends Component { constructor(props) { @@ -94,7 +94,7 @@ export default class ActionButton extends Component { width: this.props.size, height: this.props.size, borderRadius: this.props.size / 2, - } + }; const buttonStyle = { width: this.props.size, @@ -102,13 +102,15 @@ export default class ActionButton extends Component { borderRadius: this.props.size / 2, alignItems: 'center', justifyContent: 'center', - } + }; + + const Touchable = getTouchableComponent(this.props.useNativeFeedback); return ( { this.props.onPress() @@ -243,6 +245,8 @@ ActionButton.propTypes = { degrees: PropTypes.number, verticalOrientation: PropTypes.oneOf(['up', 'down']), backgroundTappable: PropTypes.bool, + useNativeFeedback: PropTypes.bool, + activeOpacity: PropTypes.number, }; ActionButton.defaultProps = { @@ -262,6 +266,8 @@ ActionButton.defaultProps = { size: 56, verticalOrientation: 'up', backgroundTappable: false, + useNativeFeedback: true, + activeOpacity: DEFAULT_ACTIVE_OPACITY, }; const styles = StyleSheet.create({ diff --git a/ActionButtonItem.js b/ActionButtonItem.js index d6dd8b5..3362de7 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,23 +1,29 @@ import React, { Component, PropTypes } from 'react'; import { StyleSheet, Text, View, Animated, TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions, Platform } from 'react-native'; -import { shadowStyle, alignItemsMap, Touchable, isAndroid, touchableBackground } from './shared'; +import { shadowStyle, alignItemsMap, getTouchableComponent, isAndroid, touchableBackground, DEFAULT_ACTIVE_OPACITY } from './shared'; const { width: WIDTH } = Dimensions.get('window'); const SHADOW_SPACE = 10; +const TEXT_HEIGHT = 22; + const TextTouchable = isAndroid ? TouchableNativeFeedback : TouchableWithoutFeedback; export default class ActionButtonItem extends Component { static get defaultProps() { return { active: true, - spaceBetween: 15 + spaceBetween: 15, + useNativeFeedback: true, + activeOpacity: DEFAULT_ACTIVE_OPACITY, }; } static get propTypes() { return { active: PropTypes.bool, + useNativeFeedback: PropTypes.bool, + activeOpacity: PropTypes.number, } } @@ -51,15 +57,17 @@ export default class ActionButtonItem extends Component { height: size, borderRadius: size / 2, backgroundColor: this.props.buttonColor || this.props.btnColor, - } + }; if (position !== 'center') buttonStyle[position] = (this.props.parentSize-size)/2; + const Touchable = getTouchableComponent(this.props.useNativeFeedback); + return ( {this.props.title} @@ -100,7 +108,6 @@ export default class ActionButtonItem extends Component { } } -const TEXT_HEIGHT = 22; const styles = StyleSheet.create({ textContainer: { diff --git a/README.md b/README.md index 85e1f45..6bcf9c5 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,8 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | onReset | function | null | use this to set the callback that will be called after the button reset's it's items | verticalOrientation | string | "up" | direction action buttons should expand. One of: `up` or `down` | backgroundTappable | boolean | false | make background tappable in active state of ActionButton +| useNativeFeedback | boolean | true | whether to use TouchableNativeFeedback on Android +| activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity ##### ActionButton.Item: | Property | Type | Default | Description | @@ -122,3 +124,5 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | textContainerStyle | style | null | use this to set the textstyle of the button's item text container | textStyle | style | null | use this to set the textstyle of the button's item text | spaceBetween | number | 15 | use this to set the space between the Button and the text container +| useNativeFeedback | boolean | true | whether to use TouchableNativeFeedback on Android +| activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity diff --git a/shared.js b/shared.js index 90b5b93..19e4b43 100644 --- a/shared.js +++ b/shared.js @@ -1,24 +1,34 @@ import { Platform, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; +export const DEFAULT_ACTIVE_OPACITY = 0.85; + export const shadowStyle = { - shadowOpacity: 0.35, - shadowOffset: { - width: 0, height: 5, - }, - shadowColor: '#000', - shadowRadius: 3, - elevation: 5, + shadowOpacity: 0.35, + shadowOffset: { + width: 0, height: 5, + }, + shadowColor: '#000', + shadowRadius: 3, + elevation: 5, }; export const alignItemsMap = { - center: 'center', - left: 'flex-start', - right: 'flex-end' + center: 'center', + left: 'flex-start', + right: 'flex-end' }; - -export const Touchable = Platform.OS === 'ios' ? TouchableOpacity : TouchableNativeFeedback; - export const isAndroid = Platform.OS === 'android'; -export const touchableBackground = isAndroid ? Platform['Version'] >= 21 ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)') : TouchableNativeFeedback.SelectableBackground() : undefined; \ No newline at end of file +export function getTouchableComponent(useNativeFeedback) { + if (useNativeFeedback === true && isAndroid === true) { + return TouchableNativeFeedback; + } + return TouchableOpacity; +} + +export const touchableBackground = isAndroid + ? Platform['Version'] >= 21 + ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)', false) + : TouchableNativeFeedback.SelectableBackground() + : undefined; From 2ba0c7b05bea146be3391970ab37372dea800e24 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sun, 5 Mar 2017 17:01:36 +0100 Subject: [PATCH 22/74] 2.6.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6d17f63..fea256e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.2", + "version": "2.6.3", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From d4597188d7121294348cf76b8ec4849f97daa94d Mon Sep 17 00:00:00 2001 From: Kevin Favro Date: Thu, 9 Mar 2017 15:25:28 -0800 Subject: [PATCH 23/74] - replacing buttonTextColor prop with buttonTextStyle. text color will still default to white - adding support for the unimplemented text property. renaming to buttonText for consistency. - updating README to reflect new prop names --- ActionButton.js | 16 ++++++++++------ README.md | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 7a71c74..de1bb5c 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -127,17 +127,19 @@ export default class ActionButton extends Component { } _renderButtonIcon() { - const { icon, btnOutRangeTxt, buttonTextColor } = this.props; + const { icon, btnOutRangeTxt, buttonTextStyle, buttonText } = this.props; if (icon) return icon; + const textColor = buttonTextStyle.color || 'rgba(255,255,255,1)' + return ( - - + + {buttonText} ) } @@ -230,7 +232,8 @@ ActionButton.propTypes = { bgColor: PropTypes.string, buttonColor: PropTypes.string, - buttonTextColor: PropTypes.string, + buttonTextStyle: Text.propTypes.style, + buttonText: PropTypes.string, offsetX: PropTypes.number, offsetY: PropTypes.number, @@ -253,7 +256,8 @@ ActionButton.defaultProps = { active: false, bgColor: 'transparent', buttonColor: 'rgba(0,0,0,1)', - buttonTextColor: 'rgba(255,255,255,1)', + buttonTextStyle: {}, + buttonText: '+', spacing: 20, outRangeScale: 1, autoInactive: true, diff --git a/README.md b/README.md index 6bcf9c5..9f345b5 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,8 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | icon | Component | + | Custom component for ActionButton Icon | backdrop | Component | false | Custom component for use as Backdrop (i.e. [BlurView](https://github.com/react-native-fellowship/react-native-blur#blur-view), [VibrancyView](https://github.com/react-native-fellowship/react-native-blur#vibrancy-view)) | degrees | number | 135 | degrees to rotate icon -| text | string | null | use this to set a different text on the button -| buttonStyle | style | null | use this to set the textstyle of the button's text +| buttonText | string | null | use this to set a different text on the button +| buttonTextStyle | style | null | use this to set the textstyle of the button's text | onReset | function | null | use this to set the callback that will be called after the button reset's it's items | verticalOrientation | string | "up" | direction action buttons should expand. One of: `up` or `down` | backgroundTappable | boolean | false | make background tappable in active state of ActionButton From 5a289d8725d57db58063f52b378f122a08ef9553 Mon Sep 17 00:00:00 2001 From: djibouti33 Date: Thu, 9 Mar 2017 15:28:20 -0800 Subject: [PATCH 24/74] updating default value for buttonText --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f345b5..4178a96 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | icon | Component | + | Custom component for ActionButton Icon | backdrop | Component | false | Custom component for use as Backdrop (i.e. [BlurView](https://github.com/react-native-fellowship/react-native-blur#blur-view), [VibrancyView](https://github.com/react-native-fellowship/react-native-blur#vibrancy-view)) | degrees | number | 135 | degrees to rotate icon -| buttonText | string | null | use this to set a different text on the button +| buttonText | string | + | use this to set a different text on the button | buttonTextStyle | style | null | use this to set the textstyle of the button's text | onReset | function | null | use this to set the callback that will be called after the button reset's it's items | verticalOrientation | string | "up" | direction action buttons should expand. One of: `up` or `down` From 123677fa51c98c5b812c168f38d28805218e784f Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Fri, 10 Mar 2017 12:14:37 +0100 Subject: [PATCH 25/74] 2.6.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fea256e..a54ff73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.3", + "version": "2.6.4", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 478f2308158184dc69a38331a6b5ecd2158ddd7d Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 23 Mar 2017 00:27:40 -0700 Subject: [PATCH 26/74] Add a prop to control the base elevation of the action button --- ActionButton.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ActionButton.js b/ActionButton.js index de1bb5c..db8e215 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -39,6 +39,7 @@ export default class ActionButton extends Component { return [ styles.overlay, { + elevation: this.props.elevation, justifyContent: this.props.verticalOrientation === 'up' ? 'flex-end' : 'flex-start' } ] @@ -227,6 +228,7 @@ ActionButton.propTypes = { active: PropTypes.bool, position: PropTypes.string, + elevation: PropTypes.number, hideShadow: PropTypes.bool, From c93f5be7160ced2ef1c57f105d51757583bc9377 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 23 Mar 2017 00:30:55 -0700 Subject: [PATCH 27/74] Add a prop to control the background opacity --- ActionButton.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ActionButton.js b/ActionButton.js index db8e215..5bd6324 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -55,7 +55,10 @@ export default class ActionButton extends Component { {this.props.backdrop} @@ -233,6 +236,7 @@ ActionButton.propTypes = { hideShadow: PropTypes.bool, bgColor: PropTypes.string, + bgOpacity: PropTypes.number, buttonColor: PropTypes.string, buttonTextStyle: Text.propTypes.style, buttonText: PropTypes.string, @@ -257,6 +261,7 @@ ActionButton.propTypes = { ActionButton.defaultProps = { active: false, bgColor: 'transparent', + bgOpacity: 1, buttonColor: 'rgba(0,0,0,1)', buttonTextStyle: {}, buttonText: '+', From 99f211f6db019d7c0dd3f5c081cd7126f3274c61 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sun, 26 Mar 2017 22:20:12 +0200 Subject: [PATCH 28/74] 2.6.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a54ff73..8ea4d13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.4", + "version": "2.6.5", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 17251f641f4488a0d9920cd4b79a585a7e1c8a15 Mon Sep 17 00:00:00 2001 From: Yusmar Castro Vera Date: Thu, 6 Apr 2017 10:07:54 -0400 Subject: [PATCH 29/74] Update ActionButton.js --- ActionButton.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ActionButton.js b/ActionButton.js index 5bd6324..e578059 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -8,6 +8,7 @@ export default class ActionButton extends Component { super(props); this.state = { + resetToken: props.resetToken, active: props.active, } @@ -19,6 +20,11 @@ export default class ActionButton extends Component { clearTimeout(this.timeout); } + componentWillReceiveProps(nextProps) + { + if (nextProps.resetToken !== this.state.resetToken) + this.setState({ resetToken: nextProps.resetToken, active: nextProps.active }); + } ////////////////////// // STYLESHEET GETTERS @@ -228,6 +234,7 @@ export default class ActionButton extends Component { ActionButton.Item = ActionButtonItem; ActionButton.propTypes = { + resetToken: PropTypes.any, active: PropTypes.bool, position: PropTypes.string, @@ -259,6 +266,7 @@ ActionButton.propTypes = { }; ActionButton.defaultProps = { + resetToken: null, active: false, bgColor: 'transparent', bgOpacity: 1, From d72b459a1c2256b0bafa1a6519e90504a17fb42f Mon Sep 17 00:00:00 2001 From: Yusmar Castro Vera Date: Fri, 7 Apr 2017 15:36:50 -0400 Subject: [PATCH 30/74] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4178a96..ab580dc 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 ##### ActionButton: | Property | Type | Default | Description | | ------------- |:-------------:|:------------: | ----------- | +| resetToken | any | null | use this to reset the internal component state (expand/collapse) in a re-render cycle. Synchronize the component state. | active | boolean | false | action buttons visible or not | autoInactive | boolean | true | Auto hide ActionButtons when ActionButton.Item is pressed. | hideShadow | boolean | false | use this to hide the default elevation and boxShadow From 620e4bf9efbe9cecafbdbd4fbfdf0dcef227b8ca Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Fri, 7 Apr 2017 21:40:29 +0200 Subject: [PATCH 31/74] 2.6.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ea4d13..79fb5a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.5", + "version": "2.6.6", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 5da3015b11bf508c42eab4a0514cba0c61ba6e0c Mon Sep 17 00:00:00 2001 From: Yusmar Castro Vera Date: Mon, 10 Apr 2017 18:47:22 -0400 Subject: [PATCH 32/74] fixing animation problems when reseting the state. (#166) * Update ActionButton.js * Update README.md * Update ActionButton.js * Update ActionButton.js --- ActionButton.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index e578059..178f1ea 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -23,7 +23,24 @@ export default class ActionButton extends Component { componentWillReceiveProps(nextProps) { if (nextProps.resetToken !== this.state.resetToken) + { + if (nextProps.active === false && this.state.active === true) + { + if (this.props.onReset) this.props.onReset(); + Animated.spring(this.anim, { toValue: 0 }).start(); + setTimeout(() => this.setState({ active: false, resetToken: nextProps.resetToken }), 250); + return; + } + + if (nextProps.active === true && this.state.active === false) + { + Animated.spring(this.anim, { toValue: 1 }).start(); + this.setState({ active: true, resetToken: nextProps.resetToken }); + return; + } + this.setState({ resetToken: nextProps.resetToken, active: nextProps.active }); + } } ////////////////////// @@ -156,7 +173,7 @@ export default class ActionButton extends Component { _renderActions() { const { children, verticalOrientation } = this.props; - + if (!this.state.active) return null; const actionButtons = !Array.isArray(children) ? [children] : children; @@ -215,7 +232,7 @@ export default class ActionButton extends Component { this.anim.setValue(1); } - this.setState({ active: true }); + this.setState({ active: true, resetToken: this.state.resetToken }); } reset(animate=true) { @@ -227,7 +244,7 @@ export default class ActionButton extends Component { this.anim.setValue(0); } - setTimeout(() => this.setState({ active: false }), 250); + setTimeout(() => this.setState({ active: false, resetToken: this.state.resetToken }), 250); } } From d50dce449101b394b7b3e1eb021fe56dda1e9ec3 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Tue, 11 Apr 2017 00:47:47 +0200 Subject: [PATCH 33/74] 2.6.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 79fb5a7..64da42d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.6", + "version": "2.6.7", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 4ee64d04bc91ef9a35de10e9b95bbd5b4a008667 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 13 Apr 2017 01:42:13 -0700 Subject: [PATCH 34/74] Add a prop to control the base zIndex of the action button. --- ActionButton.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ActionButton.js b/ActionButton.js index 178f1ea..a650b44 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -63,6 +63,7 @@ export default class ActionButton extends Component { styles.overlay, { elevation: this.props.elevation, + zIndex: this.props.zIndex, justifyContent: this.props.verticalOrientation === 'up' ? 'flex-end' : 'flex-start' } ] @@ -256,6 +257,7 @@ ActionButton.propTypes = { position: PropTypes.string, elevation: PropTypes.number, + zIndex: PropTypes.number, hideShadow: PropTypes.bool, From a2283bce26eed2da8db23fc522cc2a0710162522 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Thu, 13 Apr 2017 18:41:06 +0200 Subject: [PATCH 35/74] 2.6.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64da42d..eac7cce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.7", + "version": "2.6.8", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 37820b57b1d08ab838da7ae4dc224c383f8b8922 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Sat, 15 Apr 2017 16:16:25 -0700 Subject: [PATCH 36/74] Apply passed zIndex to the buttons to put them above the overlay --- ActionButton.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index a650b44..8821686 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -135,7 +135,7 @@ export default class ActionButton extends Component { const Touchable = getTouchableComponent(this.props.useNativeFeedback); return ( - + Date: Tue, 18 Apr 2017 15:11:36 +0200 Subject: [PATCH 37/74] 2.6.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eac7cce..6b0fd17 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.8", + "version": "2.6.9", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From fb6612305eda69bd36b1a6a2a3f98e0d7d7bc4e8 Mon Sep 17 00:00:00 2001 From: Diogo Moreira Date: Tue, 14 Feb 2017 23:43:58 +0000 Subject: [PATCH 38/74] Add support to hide ActionButtonItem and/or its label shadows --- ActionButtonItem.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 3362de7..1aa68db 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,5 +1,5 @@ import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, +import { StyleSheet, Text, View, Animated, TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions, Platform } from 'react-native'; import { shadowStyle, alignItemsMap, getTouchableComponent, isAndroid, touchableBackground, DEFAULT_ACTIVE_OPACITY } from './shared'; @@ -83,9 +83,10 @@ export default class ActionButtonItem extends Component { _renderTitle() { if (!this.props.title) return null; - const { textContainerStyle, hideShadow, offsetX, parentSize, size, position, spaceBetween } = this.props; + const { textContainerStyle, hideLabelShadow, offsetX, parentSize, size, position, spaceBetween } = this.props; const offsetTop = Math.max((size / 2) - (TEXT_HEIGHT/2), 0); const positionStyles = { top: offsetTop }; + const hideShadow = hideLabelShadow === undefined ? this.props.hideShadow : hideLabelShadow; if (position !== 'center') { positionStyles[position] = offsetX + (parentSize-size)/2 + size + spaceBetween; From 430eeb92f83dfe01a6bcd0d8895cf88ea6b2a191 Mon Sep 17 00:00:00 2001 From: Diogo Moreira Date: Thu, 8 Jun 2017 16:49:14 +0100 Subject: [PATCH 39/74] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ab580dc..d4d353e 100644 --- a/README.md +++ b/README.md @@ -127,3 +127,4 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | spaceBetween | number | 15 | use this to set the space between the Button and the text container | useNativeFeedback | boolean | true | whether to use TouchableNativeFeedback on Android | activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity +| hideLabelShadow | boolean | same as hideShadow | use this to hide the button's label default elevation and boxShadow From ef55123206270d3803b6fd03a34d3ac6f0ffd71d Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 10 Jun 2017 00:29:31 +0200 Subject: [PATCH 40/74] 2.6.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6b0fd17..2297df7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.9", + "version": "2.6.10", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 9d77fa0092575cb762aef185ce94d6a0353c2826 Mon Sep 17 00:00:00 2001 From: Ioannis Kokkinidis Date: Sat, 17 Jun 2017 17:51:28 +0300 Subject: [PATCH 41/74] Package of fixes and new features (Read on): (#185) * - Added access to shadow props via the prop shadowStyle. * The text container style is now overwriting the shadowStyle if needed. * Exposed the container view style property. * No longer allowing font scaling on the btn title text. * Fixed the TouchableNativeFeedback ripple off bounds bug on Android. - Added the fixNativeFeedbackRadius bool prop, set it to true otherwise nothing changes in the old code. - Added the nativeFeedbackRippleColor prop, to set the color of the ripple on TouchableNativeFeedback * Updated Readme.md - Also renamed props.style to props.shadowStyle - The shadowStyle prop now only works when hideShadow is inactive --- ActionButton.js | 24 +++++++++++++++++++----- ActionButtonItem.js | 40 ++++++++++++++++++++++++---------------- README.md | 11 +++++++++-- shared.js | 15 ++++++++++----- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 8821686..4814170 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -76,7 +76,7 @@ export default class ActionButton extends Component { render() { return ( - + + { this.props.onPress() if (this.props.children) this.animateButton() }}> - + {this._renderButtonIcon()} @@ -261,6 +265,11 @@ ActionButton.propTypes = { zIndex: PropTypes.number, hideShadow: PropTypes.bool, + shadowStyle: React.PropTypes.oneOfType([ + React.PropTypes.object, + React.PropTypes.array, + React.PropTypes.number, + ]), bgColor: PropTypes.string, bgOpacity: PropTypes.number, @@ -281,8 +290,11 @@ ActionButton.propTypes = { degrees: PropTypes.number, verticalOrientation: PropTypes.oneOf(['up', 'down']), backgroundTappable: PropTypes.bool, - useNativeFeedback: PropTypes.bool, activeOpacity: PropTypes.number, + + useNativeFeedback: PropTypes.bool, + fixNativeFeedbackRadius: PropTypes.bool, + nativeFeedbackRippleColor: PropTypes.string, }; ActionButton.defaultProps = { @@ -307,6 +319,8 @@ ActionButton.defaultProps = { backgroundTappable: false, useNativeFeedback: true, activeOpacity: DEFAULT_ACTIVE_OPACITY, + fixNativeFeedbackRadius: false, + nativeFeedbackRippleColor: 'rgba(255,255,255,0.75)', }; const styles = StyleSheet.create({ diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 1aa68db..26a9b6e 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -16,6 +16,8 @@ export default class ActionButtonItem extends Component { spaceBetween: 15, useNativeFeedback: true, activeOpacity: DEFAULT_ACTIVE_OPACITY, + fixNativeFeedbackRadius: true, + nativeFeedbackRippleColor: 'rgba(255,255,255,0.75)', }; } @@ -23,6 +25,8 @@ export default class ActionButtonItem extends Component { return { active: PropTypes.bool, useNativeFeedback: PropTypes.bool, + fixNativeFeedbackRadius: PropTypes.bool, + nativeFeedbackRippleColor: PropTypes.string, activeOpacity: PropTypes.number, } } @@ -33,9 +37,7 @@ export default class ActionButtonItem extends Component { if (!this.props.active) return null; const animatedViewStyle = { - height: size + SHADOW_SPACE + spacing, marginBottom: -SHADOW_SPACE, - paddingHorizontal: this.props.offsetX, alignItems: alignItemsMap[position], // backgroundColor: this.props.buttonColor, @@ -63,18 +65,24 @@ export default class ActionButtonItem extends Component { const Touchable = getTouchableComponent(this.props.useNativeFeedback); + const parentStyle = Platform.OS === 'android' && this.props.fixNativeFeedbackRadius ? + { height: size, marginBottom: spacing, right: this.props.offsetX, borderRadius: this.props.size / 2 } + : + { paddingHorizontal: this.props.offsetX, height: size + SHADOW_SPACE + spacing }; return ( - - - - {this.props.children} - - + + + + + {this.props.children} + + + {this._renderTitle()} ); @@ -94,15 +102,15 @@ export default class ActionButtonItem extends Component { positionStyles.right = WIDTH/2 + size/2 + spaceBetween; } - const textStyles = [styles.textContainer, positionStyles, textContainerStyle, !hideShadow && shadowStyle]; + const textStyles = [styles.textContainer, positionStyles, !hideShadow && shadowStyle, textContainerStyle]; return ( - {this.props.title} + {this.props.title} ); diff --git a/README.md b/README.md index d4d353e..53ebc6f 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,12 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | onReset | function | null | use this to set the callback that will be called after the button reset's it's items | verticalOrientation | string | "up" | direction action buttons should expand. One of: `up` or `down` | backgroundTappable | boolean | false | make background tappable in active state of ActionButton -| useNativeFeedback | boolean | true | whether to use TouchableNativeFeedback on Android | activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity +| shadowStyle | style | null | The custom shadow style you want to pass in the action button +| useNativeFeedback | boolean | true | Android: Whether to use a TouchableNativeFeedback +| fixNativeFeedbackRadius | boolean | false | Android: Activate this to fix TouchableNativeFeedback Ripple UI problems +| nativeFeedbackRippleColor | string | 'rgba(255,255,255,0.75)' | Android: Pass a color to the Ripple Effect of a TouchableNativeFeedback + ##### ActionButton.Item: | Property | Type | Default | Description | @@ -125,6 +129,9 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | textContainerStyle | style | null | use this to set the textstyle of the button's item text container | textStyle | style | null | use this to set the textstyle of the button's item text | spaceBetween | number | 15 | use this to set the space between the Button and the text container -| useNativeFeedback | boolean | true | whether to use TouchableNativeFeedback on Android | activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity | hideLabelShadow | boolean | same as hideShadow | use this to hide the button's label default elevation and boxShadow +| shadowStyle | style | null | The custom shadow style you want to pass in the action button item +| useNativeFeedback | boolean | true | Android: Whether to use a TouchableNativeFeedback +| fixNativeFeedbackRadius | boolean | false | Android: Activate this to fix TouchableNativeFeedback Ripple UI problems +| nativeFeedbackRippleColor | string | 'rgba(255,255,255,0.75)' | Android: Pass a color to the Ripple Effect of a TouchableNativeFeedback diff --git a/shared.js b/shared.js index 19e4b43..b4e388b 100644 --- a/shared.js +++ b/shared.js @@ -27,8 +27,13 @@ export function getTouchableComponent(useNativeFeedback) { return TouchableOpacity; } -export const touchableBackground = isAndroid - ? Platform['Version'] >= 21 - ? TouchableNativeFeedback.Ripple('rgba(255,255,255,0.75)', false) - : TouchableNativeFeedback.SelectableBackground() - : undefined; +export function touchableBackground(color, fixRadius) { + if (isAndroid) { + if (Platform['Version'] >= 21) { + return TouchableNativeFeedback.Ripple(color || 'rgba(255,255,255,0.75)', fixRadius) + } else { + TouchableNativeFeedback.SelectableBackground() + } + } + return undefined; +} From f952922f0bf16ff2428f95e7f305e16e6caafedc Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sat, 17 Jun 2017 16:52:28 +0200 Subject: [PATCH 42/74] 2.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2297df7..53dddcd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.6.10", + "version": "2.7.0", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From a6ddacf2c6dcabe2fd0afaee149f0cb9156607d8 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Fri, 23 Jun 2017 12:09:35 +0200 Subject: [PATCH 43/74] - revert some changes made in #185 - use prettier on code --- ActionButton.js | 274 +++++++++++++++++++++++++++----------------- ActionButtonItem.js | 163 ++++++++++++++++++-------- shared.js | 32 ++++-- 3 files changed, 307 insertions(+), 162 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 4814170..6d83006 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,7 +1,21 @@ -import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, TouchableOpacity, Platform } from 'react-native'; -import ActionButtonItem from './ActionButtonItem'; -import { shadowStyle, alignItemsMap, getTouchableComponent, isAndroid, touchableBackground, DEFAULT_ACTIVE_OPACITY } from './shared'; +import React, { Component, PropTypes } from "react"; +import { + StyleSheet, + Text, + View, + Animated, + TouchableOpacity, + Platform +} from "react-native"; +import ActionButtonItem from "./ActionButtonItem"; +import { + shadowStyle, + alignItemsMap, + getTouchableComponent, + isAndroid, + touchableBackground, + DEFAULT_ACTIVE_OPACITY +} from "./shared"; export default class ActionButton extends Component { constructor(props) { @@ -9,8 +23,8 @@ export default class ActionButton extends Component { this.state = { resetToken: props.resetToken, - active: props.active, - } + active: props.active + }; this.anim = new Animated.Value(props.active ? 1 : 0); this.timeout = null; @@ -20,27 +34,30 @@ export default class ActionButton extends Component { clearTimeout(this.timeout); } - componentWillReceiveProps(nextProps) - { - if (nextProps.resetToken !== this.state.resetToken) - { - if (nextProps.active === false && this.state.active === true) - { - if (this.props.onReset) this.props.onReset(); - Animated.spring(this.anim, { toValue: 0 }).start(); - setTimeout(() => this.setState({ active: false, resetToken: nextProps.resetToken }), 250); - return; - } + componentWillReceiveProps(nextProps) { + if (nextProps.resetToken !== this.state.resetToken) { + if (nextProps.active === false && this.state.active === true) { + if (this.props.onReset) this.props.onReset(); + Animated.spring(this.anim, { toValue: 0 }).start(); + setTimeout( + () => + this.setState({ active: false, resetToken: nextProps.resetToken }), + 250 + ); + return; + } - if (nextProps.active === true && this.state.active === false) - { - Animated.spring(this.anim, { toValue: 1 }).start(); - this.setState({ active: true, resetToken: nextProps.resetToken }); - return; - } + if (nextProps.active === true && this.state.active === false) { + Animated.spring(this.anim, { toValue: 1 }).start(); + this.setState({ active: true, resetToken: nextProps.resetToken }); + return; + } - this.setState({ resetToken: nextProps.resetToken, active: nextProps.active }); - } + this.setState({ + resetToken: nextProps.resetToken, + active: nextProps.active + }); + } } ////////////////////// @@ -64,36 +81,57 @@ export default class ActionButton extends Component { { elevation: this.props.elevation, zIndex: this.props.zIndex, - justifyContent: this.props.verticalOrientation === 'up' ? 'flex-end' : 'flex-start' + justifyContent: this.props.verticalOrientation === "up" + ? "flex-end" + : "flex-start" } - ] + ]; } - ////////////////////// // RENDER METHODS ////////////////////// render() { return ( - - + + {this.props.backdrop} - - {(this.state.active && !this.props.backgroundTappable) && this._renderTappableBackground()} - - {this.props.verticalOrientation === 'up' && - this.props.children && this._renderActions()} + + {this.state.active && + !this.props.backgroundTappable && + this._renderTappableBackground()} + + {this.props.verticalOrientation === "up" && + this.props.children && + this._renderActions()} {this._renderMainButton()} - {this.props.verticalOrientation === 'down' && - this.props.children && this._renderActions()} + {this.props.verticalOrientation === "down" && + this.props.children && + this._renderActions()} ); @@ -101,54 +139,75 @@ export default class ActionButton extends Component { _renderMainButton() { const animatedViewStyle = { - transform: [{ - scale: this.anim.interpolate({ - inputRange: [0, 1], - outputRange: [1, this.props.outRangeScale] - }), - }, { - rotate: this.anim.interpolate({ - inputRange: [0, 1], - outputRange: ['0deg', this.props.degrees + 'deg'] - }) - }], + transform: [ + { + scale: this.anim.interpolate({ + inputRange: [0, 1], + outputRange: [1, this.props.outRangeScale] + }) + }, + { + rotate: this.anim.interpolate({ + inputRange: [0, 1], + outputRange: ["0deg", this.props.degrees + "deg"] + }) + } + ] }; const wrapperStyle = { backgroundColor: this.anim.interpolate({ inputRange: [0, 1], - outputRange: [this.props.buttonColor, (this.props.btnOutRange || this.props.buttonColor)] + outputRange: [ + this.props.buttonColor, + this.props.btnOutRange || this.props.buttonColor + ] }), width: this.props.size, height: this.props.size, - borderRadius: this.props.size / 2, + borderRadius: this.props.size / 2 }; const buttonStyle = { width: this.props.size, height: this.props.size, borderRadius: this.props.size / 2, - alignItems: 'center', - justifyContent: 'center', + alignItems: "center", + justifyContent: "center" }; const Touchable = getTouchableComponent(this.props.useNativeFeedback); - const parentStyle = Platform.OS === 'android' && this.props.fixNativeFeedbackRadius? - { right: this.props.offsetX, zIndex: this.props.zIndex, borderRadius: this.props.size / 2, width: this.props.size } - : - { paddingHorizontal: this.props.offsetX, zIndex: this.props.zIndex } + const parentStyle = Platform.OS === "android" && + this.props.fixNativeFeedbackRadius + ? { + right: this.props.offsetX, + zIndex: this.props.zIndex, + borderRadius: this.props.size / 2, + width: this.props.size + } + : { paddingHorizontal: this.props.offsetX, zIndex: this.props.zIndex }; return ( { - this.props.onPress() - if (this.props.children) this.animateButton() - }}> - + this.props.onPress(); + if (this.props.children) this.animateButton(); + }} + > + {this._renderButtonIcon()} @@ -162,38 +221,46 @@ export default class ActionButton extends Component { const { icon, btnOutRangeTxt, buttonTextStyle, buttonText } = this.props; if (icon) return icon; - const textColor = buttonTextStyle.color || 'rgba(255,255,255,1)' + const textColor = buttonTextStyle.color || "rgba(255,255,255,1)"; return ( - + {buttonText} - ) + ); } _renderActions() { const { children, verticalOrientation } = this.props; - + if (!this.state.active) return null; const actionButtons = !Array.isArray(children) ? [children] : children; const actionStyle = { flex: 1, - alignSelf: 'stretch', + alignSelf: "stretch", // backgroundColor: 'purple', - justifyContent: verticalOrientation === 'up' ? 'flex-end' : 'flex-start', - paddingTop: this.props.verticalOrientation === 'down' ? this.props.spacing : 0, - zIndex: this.props.zIndex, + justifyContent: verticalOrientation === "up" ? "flex-end" : "flex-start", + paddingTop: this.props.verticalOrientation === "down" + ? this.props.spacing + : 0, + zIndex: this.props.zIndex }; return ( - + {actionButtons.map((ActionButton, idx) => (  { - if (this.props.autoInactive){ + onPress={() => { + if (this.props.autoInactive) { this.timeout = setTimeout(this.reset.bind(this), 200); } ActionButton.props.onPress(); @@ -224,12 +291,11 @@ export default class ActionButton extends Component { ); } - ////////////////////// // Animation Methods ////////////////////// - animateButton(animate=true) { + animateButton(animate = true) { if (this.state.active) return this.reset(); if (animate) { @@ -241,7 +307,7 @@ export default class ActionButton extends Component { this.setState({ active: true, resetToken: this.state.resetToken }); } - reset(animate=true) { + reset(animate = true) { if (this.props.onReset) this.props.onReset(); if (animate) { @@ -250,7 +316,10 @@ export default class ActionButton extends Component { this.anim.setValue(0); } - setTimeout(() => this.setState({ active: false, resetToken: this.state.resetToken }), 250); + setTimeout( + () => this.setState({ active: false, resetToken: this.state.resetToken }), + 250 + ); } } @@ -268,7 +337,7 @@ ActionButton.propTypes = { shadowStyle: React.PropTypes.oneOfType([ React.PropTypes.object, React.PropTypes.array, - React.PropTypes.number, + React.PropTypes.number ]), bgColor: PropTypes.string, @@ -283,58 +352,55 @@ ActionButton.propTypes = { size: PropTypes.number, autoInactive: PropTypes.bool, onPress: PropTypes.func, - backdrop: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.object - ]), + backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), degrees: PropTypes.number, - verticalOrientation: PropTypes.oneOf(['up', 'down']), + verticalOrientation: PropTypes.oneOf(["up", "down"]), backgroundTappable: PropTypes.bool, activeOpacity: PropTypes.number, useNativeFeedback: PropTypes.bool, fixNativeFeedbackRadius: PropTypes.bool, - nativeFeedbackRippleColor: PropTypes.string, + nativeFeedbackRippleColor: PropTypes.string }; ActionButton.defaultProps = { resetToken: null, active: false, - bgColor: 'transparent', + bgColor: "transparent", bgOpacity: 1, - buttonColor: 'rgba(0,0,0,1)', + buttonColor: "rgba(0,0,0,1)", buttonTextStyle: {}, - buttonText: '+', + buttonText: "+", spacing: 20, outRangeScale: 1, autoInactive: true, onPress: () => {}, backdrop: false, degrees: 45, - position: 'right', + position: "right", offsetX: 30, offsetY: 30, size: 56, - verticalOrientation: 'up', + verticalOrientation: "up", backgroundTappable: false, useNativeFeedback: true, activeOpacity: DEFAULT_ACTIVE_OPACITY, fixNativeFeedbackRadius: false, - nativeFeedbackRippleColor: 'rgba(255,255,255,0.75)', + nativeFeedbackRippleColor: "rgba(255,255,255,0.75)" }; const styles = StyleSheet.create({ overlay: { - position: 'absolute', + position: "absolute", bottom: 0, left: 0, right: 0, top: 0, - backgroundColor: 'transparent', + backgroundColor: "transparent" }, btnText: { marginTop: -4, fontSize: 24, - backgroundColor: 'transparent', - }, + backgroundColor: "transparent" + } }); diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 26a9b6e..d5f1acf 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,13 +1,30 @@ -import React, { Component, PropTypes } from 'react'; -import { StyleSheet, Text, View, Animated, - TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions, Platform } from 'react-native'; -import { shadowStyle, alignItemsMap, getTouchableComponent, isAndroid, touchableBackground, DEFAULT_ACTIVE_OPACITY } from './shared'; - -const { width: WIDTH } = Dimensions.get('window'); +import React, { Component, PropTypes } from "react"; +import { + StyleSheet, + Text, + View, + Animated, + TouchableNativeFeedback, + TouchableWithoutFeedback, + Dimensions, + Platform +} from "react-native"; +import { + shadowStyle, + alignItemsMap, + getTouchableComponent, + isAndroid, + touchableBackground, + DEFAULT_ACTIVE_OPACITY +} from "./shared"; + +const { width: WIDTH } = Dimensions.get("window"); const SHADOW_SPACE = 10; const TEXT_HEIGHT = 22; -const TextTouchable = isAndroid ? TouchableNativeFeedback : TouchableWithoutFeedback; +const TextTouchable = isAndroid + ? TouchableNativeFeedback + : TouchableWithoutFeedback; export default class ActionButtonItem extends Component { static get defaultProps() { @@ -16,8 +33,8 @@ export default class ActionButtonItem extends Component { spaceBetween: 15, useNativeFeedback: true, activeOpacity: DEFAULT_ACTIVE_OPACITY, - fixNativeFeedbackRadius: true, - nativeFeedbackRippleColor: 'rgba(255,255,255,0.75)', + fixNativeFeedbackRadius: false, + nativeFeedbackRippleColor: "rgba(255,255,255,0.75)" }; } @@ -27,12 +44,18 @@ export default class ActionButtonItem extends Component { useNativeFeedback: PropTypes.bool, fixNativeFeedbackRadius: PropTypes.bool, nativeFeedbackRippleColor: PropTypes.string, - activeOpacity: PropTypes.number, - } + activeOpacity: PropTypes.number + }; } render() { - const { size, position, verticalOrientation, hideShadow, spacing } = this.props; + const { + size, + position, + verticalOrientation, + hideShadow, + spacing + } = this.props; if (!this.props.active) return null; @@ -46,39 +69,63 @@ export default class ActionButtonItem extends Component { { translateY: this.props.anim.interpolate({ inputRange: [0, 1], - outputRange: [verticalOrientation === 'down' ? -40 : 40, 0] - }), + outputRange: [verticalOrientation === "down" ? -40 : 40, 0] + }) } - ], + ] }; const buttonStyle = { - justifyContent: 'center', - alignItems: 'center', + justifyContent: "center", + alignItems: "center", width: size, height: size, borderRadius: size / 2, - backgroundColor: this.props.buttonColor || this.props.btnColor, + backgroundColor: this.props.buttonColor || this.props.btnColor }; - if (position !== 'center') buttonStyle[position] = (this.props.parentSize-size)/2; + if (position !== "center") + buttonStyle[position] = (this.props.parentSize - size) / 2; const Touchable = getTouchableComponent(this.props.useNativeFeedback); - const parentStyle = Platform.OS === 'android' && this.props.fixNativeFeedbackRadius ? - { height: size, marginBottom: spacing, right: this.props.offsetX, borderRadius: this.props.size / 2 } - : - { paddingHorizontal: this.props.offsetX, height: size + SHADOW_SPACE + spacing }; + const parentStyle = Platform.OS === "android" && + this.props.fixNativeFeedbackRadius + ? { + height: size, + marginBottom: spacing, + right: this.props.offsetX, + borderRadius: this.props.size / 2 + } + : { + paddingHorizontal: this.props.offsetX, + height: size + SHADOW_SPACE + spacing + }; return ( - - + + - + onPress={this.props.onPress} + > + {this.props.children} @@ -91,47 +138,71 @@ export default class ActionButtonItem extends Component { _renderTitle() { if (!this.props.title) return null; - const { textContainerStyle, hideLabelShadow, offsetX, parentSize, size, position, spaceBetween } = this.props; - const offsetTop = Math.max((size / 2) - (TEXT_HEIGHT/2), 0); + const { + textContainerStyle, + hideLabelShadow, + offsetX, + parentSize, + size, + position, + spaceBetween + } = this.props; + const offsetTop = Math.max(size / 2 - TEXT_HEIGHT / 2, 0); const positionStyles = { top: offsetTop }; - const hideShadow = hideLabelShadow === undefined ? this.props.hideShadow : hideLabelShadow; + const hideShadow = hideLabelShadow === undefined + ? this.props.hideShadow + : hideLabelShadow; - if (position !== 'center') { - positionStyles[position] = offsetX + (parentSize-size)/2 + size + spaceBetween; + if (position !== "center") { + positionStyles[position] = + offsetX + (parentSize - size) / 2 + size + spaceBetween; } else { - positionStyles.right = WIDTH/2 + size/2 + spaceBetween; + positionStyles.right = WIDTH / 2 + size / 2 + spaceBetween; } - const textStyles = [styles.textContainer, positionStyles, !hideShadow && shadowStyle, textContainerStyle]; + const textStyles = [ + styles.textContainer, + positionStyles, + !hideShadow && shadowStyle, + textContainerStyle + ]; return ( + onPress={this.props.onPress} + > - {this.props.title} + + {this.props.title} + ); } } - const styles = StyleSheet.create({ textContainer: { - position: 'absolute', - paddingVertical: (isAndroid ? 2 : 3), + position: "absolute", + paddingVertical: isAndroid ? 2 : 3, paddingHorizontal: 8, borderRadius: 3, borderWidth: StyleSheet.hairlineWidth, - borderColor: '#eee', - backgroundColor: 'white', + borderColor: "#eee", + backgroundColor: "white", height: TEXT_HEIGHT }, text: { flex: 1, fontSize: 12, - color: '#444', + color: "#444" } }); diff --git a/shared.js b/shared.js index b4e388b..44aa9c7 100644 --- a/shared.js +++ b/shared.js @@ -1,38 +1,46 @@ -import { Platform, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; +import { + Platform, + TouchableOpacity, + TouchableNativeFeedback +} from "react-native"; export const DEFAULT_ACTIVE_OPACITY = 0.85; export const shadowStyle = { shadowOpacity: 0.35, shadowOffset: { - width: 0, height: 5, + width: 0, + height: 5 }, - shadowColor: '#000', + shadowColor: "#000", shadowRadius: 3, - elevation: 5, + elevation: 5 }; export const alignItemsMap = { - center: 'center', - left: 'flex-start', - right: 'flex-end' + center: "center", + left: "flex-start", + right: "flex-end" }; -export const isAndroid = Platform.OS === 'android'; +export const isAndroid = Platform.OS === "android"; export function getTouchableComponent(useNativeFeedback) { if (useNativeFeedback === true && isAndroid === true) { return TouchableNativeFeedback; } - return TouchableOpacity; + return TouchableOpacity; } export function touchableBackground(color, fixRadius) { if (isAndroid) { - if (Platform['Version'] >= 21) { - return TouchableNativeFeedback.Ripple(color || 'rgba(255,255,255,0.75)', fixRadius) + if (Platform["Version"] >= 21) { + return TouchableNativeFeedback.Ripple( + color || "rgba(255,255,255,0.75)", + fixRadius + ); } else { - TouchableNativeFeedback.SelectableBackground() + TouchableNativeFeedback.SelectableBackground(); } } return undefined; From f3b897a54a0ca939efeeedfbeb6ce5dbcd9064aa Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Fri, 23 Jun 2017 12:14:13 +0200 Subject: [PATCH 44/74] 2.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 53dddcd..a8ada62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.7.0", + "version": "2.7.1", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From dc2c2ec0777afc29bb79b0864b694ab78c70254d Mon Sep 17 00:00:00 2001 From: alphasp Date: Mon, 10 Jul 2017 19:55:13 +0800 Subject: [PATCH 45/74] Migrate deprecated React.PropTypes (#195) * added gitignore * migrate deprecated React.propTypes --- .gitignore | 40 ++++++++++++++++++++++++++++++++++++++++ ActionButton.js | 11 ++++++----- ActionButtonItem.js | 3 ++- package.json | 5 ++++- 4 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27e3ca1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + + +.idea diff --git a/ActionButton.js b/ActionButton.js index 6d83006..d8402af 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { StyleSheet, Text, @@ -334,10 +335,10 @@ ActionButton.propTypes = { zIndex: PropTypes.number, hideShadow: PropTypes.bool, - shadowStyle: React.PropTypes.oneOfType([ - React.PropTypes.object, - React.PropTypes.array, - React.PropTypes.number + shadowStyle: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.array, + PropTypes.number ]), bgColor: PropTypes.string, diff --git a/ActionButtonItem.js b/ActionButtonItem.js index d5f1acf..e58ae03 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { StyleSheet, Text, diff --git a/package.json b/package.json index a8ada62..7b6bc93 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,8 @@ "bugs": { "url": "https://github.com/mastermoo/react-native-action-button/issues" }, - "homepage": "https://github.com/mastermoo/react-native-action-button" + "homepage": "https://github.com/mastermoo/react-native-action-button", + "dependencies": { + "prop-types": "^15.5.10" + } } From 24850b7314370849533fff2b8087853fdcaea0aa Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Mon, 10 Jul 2017 13:55:40 +0200 Subject: [PATCH 46/74] 2.7.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b6bc93..5ff2f9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.7.1", + "version": "2.7.2", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 49c628343880aa9c044de3a09331dc6d132d78c5 Mon Sep 17 00:00:00 2001 From: Adrian S Date: Thu, 31 Aug 2017 17:26:47 +0700 Subject: [PATCH 47/74] Remove unnecessary import (#200) --- ActionButton.js | 3 +-- ActionButtonItem.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index d8402af..2053c58 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -6,7 +6,6 @@ import { View, Animated, TouchableOpacity, - Platform } from "react-native"; import ActionButtonItem from "./ActionButtonItem"; import { @@ -178,7 +177,7 @@ export default class ActionButton extends Component { }; const Touchable = getTouchableComponent(this.props.useNativeFeedback); - const parentStyle = Platform.OS === "android" && + const parentStyle = isAndroid && this.props.fixNativeFeedbackRadius ? { right: this.props.offsetX, diff --git a/ActionButtonItem.js b/ActionButtonItem.js index e58ae03..c2640f5 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -8,7 +8,6 @@ import { TouchableNativeFeedback, TouchableWithoutFeedback, Dimensions, - Platform } from "react-native"; import { shadowStyle, @@ -90,7 +89,7 @@ export default class ActionButtonItem extends Component { const Touchable = getTouchableComponent(this.props.useNativeFeedback); - const parentStyle = Platform.OS === "android" && + const parentStyle = isAndroid && this.props.fixNativeFeedbackRadius ? { height: size, From 42fd7034f12a012d4820a0a4113c68f6ac455455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Sp=C3=B6ck?= Date: Thu, 31 Aug 2017 12:29:47 +0200 Subject: [PATCH 48/74] add props onPressIn and onPressOut (#216) * feat: add props onPressIn and onPressOut * doc: add props onPressIn and onPressOut --- ActionButton.js | 6 ++++++ README.md | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ActionButton.js b/ActionButton.js index 2053c58..18baf17 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -200,6 +200,8 @@ export default class ActionButton extends Component { this.props.onPress(); if (this.props.children) this.animateButton(); }} + onPressIn={this.props.onPressIn} + onPressOut={this.props.onPressOut} > {}, + onPressIn: () => {}, + onPressOn: () => {}, backdrop: false, degrees: 45, position: "right", diff --git a/README.md b/README.md index 53ebc6f..d366c12 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | btnOutRange | string | props.buttonColor | button background color to animate to | outRangeScale | number | 1 | changes size of button during animation | onPress | function | null | fires, when ActionButton is tapped +| onPressIn | function | null | fires, before ActionButton is released +| onPressOut | function | null | fires, after ActionButton is released | onLongPress | function | null | fires, when ActionButton is long pressed | icon | Component | + | Custom component for ActionButton Icon | backdrop | Component | false | Custom component for use as Backdrop (i.e. [BlurView](https://github.com/react-native-fellowship/react-native-blur#blur-view), [VibrancyView](https://github.com/react-native-fellowship/react-native-blur#vibrancy-view)) From 951b1984f86992cfcf70d2949b7a1b868ef6647d Mon Sep 17 00:00:00 2001 From: Adrian S Date: Thu, 31 Aug 2017 17:30:16 +0700 Subject: [PATCH 49/74] Add reminder for linking `react-native-vector-icons`. (#214) --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index d366c12..96f9fea 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,15 @@ customizable multi-action-button component for react-native ```bash npm i react-native-action-button --save ``` +Link `react-native-vector-icons` native dependencies to your project with: +```bash +react-native link react-native-vector-icons +``` +or just: +```bash +react-native link +``` +to link all libraries with native dependencies in your project. ### Usage From d4dbbea3ea6f9a0a069fa1a8c5dbfadd187d81f2 Mon Sep 17 00:00:00 2001 From: Adrian S Date: Thu, 31 Aug 2017 17:36:46 +0700 Subject: [PATCH 50/74] Make non-string value/component as title (#211) --- ActionButtonItem.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index c2640f5..f7f40aa 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -167,6 +167,19 @@ export default class ActionButtonItem extends Component { textContainerStyle ]; + const title = ( + React.isValidElement(this.props.title) ? + this.props.title + : ( + + {this.props.title} + + ) + ) + return ( - - {this.props.title} - + {title} ); From 3d9be2c9bda84ebe8261487d898a12c4bf2add95 Mon Sep 17 00:00:00 2001 From: Ashaya Sharma Date: Thu, 31 Aug 2017 03:39:01 -0700 Subject: [PATCH 51/74] Fix shadow style on Android (#215) --- ActionButton.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 18baf17..28340ba 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -188,7 +188,12 @@ export default class ActionButton extends Component { : { paddingHorizontal: this.props.offsetX, zIndex: this.props.zIndex }; return ( - + {this._renderButtonIcon()} From b437dd24072234533316f301cf9a8232c393099d Mon Sep 17 00:00:00 2001 From: PC Futures Date: Thu, 31 Aug 2017 11:40:49 +0100 Subject: [PATCH 52/74] Switch MainButton to use Margin not Padding, and fix shadow prop warning (#212) * Switch MainButton to use Margin not Padding Switch from `paddingHorizontal` to `marginHorizontal` * Move Shadow Props to different View Currently the shadow is rendered on an item without a background color, which causes a warning. This commit moves the shadow props to the same View that contains the backgroundColor, thus removing the warning. Makes no difference to usage/appearance. --- ActionButton.js | 2 +- ActionButtonItem.js | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 28340ba..0d82585 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -185,7 +185,7 @@ export default class ActionButton extends Component { borderRadius: this.props.size / 2, width: this.props.size } - : { paddingHorizontal: this.props.offsetX, zIndex: this.props.zIndex }; + : { marginHorizontal: this.props.offsetX, zIndex: this.props.zIndex }; return ( - + {this.props.children} From a73637cca3f43fa07d065e48ca62e828e66f3da8 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Thu, 31 Aug 2017 12:46:52 +0200 Subject: [PATCH 53/74] 2.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ff2f9c..87b8464 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.7.2", + "version": "2.8.0", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From dac08ea9e3ead862054f163107b54b14a4a5d823 Mon Sep 17 00:00:00 2001 From: Yoshihiro Misawa Date: Sat, 21 Oct 2017 01:41:08 +0900 Subject: [PATCH 54/74] fix #223 (#229) --- ActionButtonItem.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 4ca7482..466af6f 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -106,13 +106,7 @@ export default class ActionButtonItem extends Component { pointerEvents="box-none" style={[animatedViewStyle, parentStyle]} > - + Date: Fri, 20 Oct 2017 19:05:53 +0200 Subject: [PATCH 55/74] 2.8.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87b8464..7e9d5d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.0", + "version": "2.8.1", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From a0054fed853e9ee5dc9ccfb37176e791676030d4 Mon Sep 17 00:00:00 2001 From: Daniel Lacasse Date: Sun, 29 Oct 2017 18:52:45 -0400 Subject: [PATCH 56/74] Wire `testID` properly into the action buttons --- ActionButton.js | 8 ++++++-- ActionButtonItem.js | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 0d82585..8db543b 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -195,6 +195,7 @@ export default class ActionButton extends Component { ]} > Date: Tue, 14 Nov 2017 14:05:54 +0100 Subject: [PATCH 57/74] 2.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7e9d5d7..037ad3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.1", + "version": "2.8.2", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 6f9c5587ae926501ecd537af75125047ebce1606 Mon Sep 17 00:00:00 2001 From: CofCool Date: Sun, 26 Nov 2017 18:59:27 +0800 Subject: [PATCH 58/74] definition file of Typescript (#217) * definition file of Typescript --- index.d.ts | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 index.d.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..b9e44ef --- /dev/null +++ b/index.d.ts @@ -0,0 +1,60 @@ +import * as React from 'react' +import { + ViewStyle, + ViewProperties, + TextStyle +} from 'react-native' + + +export interface ActionButtonProperties extends ViewProperties { + resetToken?: any, + active?: boolean, + + position?: string, + elevation?: number, + zIndex?: number, + + hideShadow?: boolean, + shadowStyle?: {} | [any] | number, + bgColor?: string, + bgOpacity?: number, + buttonColor?: string, + buttonTextStyle?: TextStyle, + buttonText?: string, + + offsetX?: number, + offsetY?: number, + spacing?: number, + size?: number, + autoInactive?: boolean, + onPress?: () => void, + backdrop?: boolean | object, + degrees?: number, + verticalOrientation?: 'up' | 'down', + backgroundTappable?: boolean, + activeOpacity?: number, + + useNativeFeedback?: boolean, + fixNativeFeedbackRadius?: boolean, + nativeFeedbackRippleColor?: string +} + +export interface ActionButtonItemProperties extends ViewProperties { + title?: string + onPress?: () => void + buttonColor?: string + textContainerStyle?: ViewStyle + textStyle?: TextStyle + spaceBetween?: number + activeOpacity?: number + hideLabelShadow?: boolean + shadowStyle?: ViewStyle + useNativeFeedback?: boolean + fixNativeFeedbackRadius?: boolean + nativeFeedbackRippleColor?: string +} + +export class ActionButtonItem extends React.Component {} +export default class ActionButton extends React.Component { + static Item: typeof ActionButtonItem +} From cd06f74c98aef61b23b6a930ca78de07e9b3cc81 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Sun, 26 Nov 2017 12:01:44 +0100 Subject: [PATCH 59/74] 2.8.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 037ad3f..dfeeef8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.2", + "version": "2.8.3", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 0ec80b8f48e7557f4495916837f7bff1925d2403 Mon Sep 17 00:00:00 2001 From: Jake Taylor Date: Thu, 25 Jan 2018 20:24:51 +0000 Subject: [PATCH 60/74] Add render prop to ActionButton (#254) * Add render prop to ActionButton * Add documentation for `renderIcon` prop * Add deprecation warning for `icon` prop --- ActionButton.js | 10 ++++++++-- README.md | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 8db543b..f4a88e1 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -222,8 +222,12 @@ export default class ActionButton extends Component { } _renderButtonIcon() { - const { icon, btnOutRangeTxt, buttonTextStyle, buttonText } = this.props; - if (icon) return icon; + const { icon, renderIcon, btnOutRangeTxt, buttonTextStyle, buttonText } = this.props; + if (renderIcon) return renderIcon(this.state.active); + if (icon) { + console.warn('react-native-action-button: The `icon` prop is deprecated! Use `renderIcon` instead.'); + return icon; + } const textColor = buttonTextStyle.color || "rgba(255,255,255,1)"; @@ -344,6 +348,8 @@ ActionButton.propTypes = { PropTypes.number ]), + renderIcon: PropTypes.func, + bgColor: PropTypes.string, bgOpacity: PropTypes.number, buttonColor: PropTypes.string, diff --git a/README.md b/README.md index 96f9fea..bb42e55 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,8 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | onPressIn | function | null | fires, before ActionButton is released | onPressOut | function | null | fires, after ActionButton is released | onLongPress | function | null | fires, when ActionButton is long pressed -| icon | Component | + | Custom component for ActionButton Icon +| renderIcon   | function | null | Function to render the component for ActionButton Icon. It is passed a boolean, `active`, which is true if the FAB has been expanded, and false if it is collapsed, allowing you to show a different icon when the ActionButton Items are expanded. +| icon         | Component     | +                   | **Deprecated, use `renderIcon`** Custom component for ActionButton Icon | backdrop | Component | false | Custom component for use as Backdrop (i.e. [BlurView](https://github.com/react-native-fellowship/react-native-blur#blur-view), [VibrancyView](https://github.com/react-native-fellowship/react-native-blur#vibrancy-view)) | degrees | number | 135 | degrees to rotate icon | buttonText | string | + | use this to set a different text on the button From 3a93a784e307230960a4d4b7fa611fdbe962261e Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Thu, 25 Jan 2018 21:46:17 +0100 Subject: [PATCH 61/74] added size to docs in readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bb42e55..860f1e3 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 ##### ActionButton: | Property | Type | Default | Description | | ------------- |:-------------:|:------------: | ----------- | +| size | number | 56 | use this to change the size of the Button | resetToken | any | null | use this to reset the internal component state (expand/collapse) in a re-render cycle. Synchronize the component state. | active | boolean | false | action buttons visible or not | autoInactive | boolean | true | Auto hide ActionButtons when ActionButton.Item is pressed. @@ -133,6 +134,7 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 ##### ActionButton.Item: | Property | Type | Default | Description | | ------------- |:-------------:|:------------: | ----------- | +| size | number | parentSize | use this to change the size of the Button | title | string | undefined | the title shown next to the button. When `undefined` the title is not hidden | onPress | func | null | **required** function, triggers when a button is tapped | buttonColor | string | same as + button | background color of the Button From c549b6adeabfe1a87f349e53e63ee99bb90c90b6 Mon Sep 17 00:00:00 2001 From: Yousef Kamawall Date: Thu, 25 Jan 2018 21:46:36 +0100 Subject: [PATCH 62/74] 2.8.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dfeeef8..df98d6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.3", + "version": "2.8.4", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From e6893e1a6e7597207eb70e4283bc17ec4079824d Mon Sep 17 00:00:00 2001 From: Toshinori Tsugita Date: Thu, 5 Jul 2018 01:44:11 +0900 Subject: [PATCH 63/74] Add size property to ActionButonItemProperties interface (#283) * which seems to have been forgotten to add when creating TypeScript interface --- index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.d.ts b/index.d.ts index b9e44ef..edae845 100644 --- a/index.d.ts +++ b/index.d.ts @@ -40,6 +40,7 @@ export interface ActionButtonProperties extends ViewProperties { } export interface ActionButtonItemProperties extends ViewProperties { + size?: number, title?: string onPress?: () => void buttonColor?: string From b81317323dd4daca06fdba63f7425afb9e494263 Mon Sep 17 00:00:00 2001 From: Juan Felipe Carrera Moya Date: Wed, 4 Jul 2018 11:44:36 -0500 Subject: [PATCH 64/74] filtering actionButtons to prevent issues with not valid childrens (#288) --- ActionButton.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index f4a88e1..11c0470 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -254,7 +254,9 @@ export default class ActionButton extends Component { if (!this.state.active) return null; - const actionButtons = !Array.isArray(children) ? [children] : children; + let actionButtons = !Array.isArray(children) ? [children] : children; + + actionButtons = actionButtons.filter( actionButton => (typeof actionButton == 'object') ) const actionStyle = { flex: 1, @@ -349,7 +351,7 @@ ActionButton.propTypes = { ]), renderIcon: PropTypes.func, - + bgColor: PropTypes.string, bgOpacity: PropTypes.number, buttonColor: PropTypes.string, From b9e850cb0c5f1f83431590fd6c822f5ca62ae28f Mon Sep 17 00:00:00 2001 From: Adam Ivancza Date: Wed, 4 Jul 2018 18:44:51 +0200 Subject: [PATCH 65/74] Prevent to update state after unmounting component (#287) --- ActionButton.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 11c0470..4aa6a10 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -30,7 +30,12 @@ export default class ActionButton extends Component { this.timeout = null; } + componentDidMount() { + this.mounted = true; + } + componentWillUnmount() { + this.mounted = false; clearTimeout(this.timeout); } @@ -326,10 +331,11 @@ export default class ActionButton extends Component { this.anim.setValue(0); } - setTimeout( - () => this.setState({ active: false, resetToken: this.state.resetToken }), - 250 - ); + setTimeout(() => { + if (this.mounted) { + this.setState({ active: false, resetToken: this.state.resetToken }); + } + }, 250); } } From 79dad1cc4ce493788a14273f7c87ae2cd3616107 Mon Sep 17 00:00:00 2001 From: Dominique Rau Date: Wed, 4 Jul 2018 18:46:13 +0200 Subject: [PATCH 66/74] Add renderIcon to definitions... (#280) --- index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.d.ts b/index.d.ts index edae845..c10dc75 100644 --- a/index.d.ts +++ b/index.d.ts @@ -28,6 +28,7 @@ export interface ActionButtonProperties extends ViewProperties { size?: number, autoInactive?: boolean, onPress?: () => void, + renderIcon?: (active: boolean) => React.ReactElement, backdrop?: boolean | object, degrees?: number, verticalOrientation?: 'up' | 'down', From 067aa6b4986b4c6c1d5e72b874df98ceeb020a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Daureh=C3=B8j?= Date: Wed, 29 Aug 2018 14:29:56 +0200 Subject: [PATCH 67/74] Added accessibleLabel (#282) * added accessibleLabel --- ActionButton.js | 10 +++- ActionButtonItem.js | 1 + package-lock.json | 127 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/ActionButton.js b/ActionButton.js index 4aa6a10..b8306c2 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -201,6 +201,8 @@ export default class ActionButton extends Component { > Date: Wed, 29 Aug 2018 14:36:12 +0200 Subject: [PATCH 68/74] 2.8.5 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5827c4..cc96fdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.4", + "version": "2.8.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index df98d6a..5cd1443 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.4", + "version": "2.8.5", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": { From 2e301b9145336a395eb73d3bb86656c2189b39a9 Mon Sep 17 00:00:00 2001 From: Gapur Kassym Date: Fri, 15 Feb 2019 10:55:51 +0600 Subject: [PATCH 69/74] fix render icon return type --- index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index c10dc75..2ba74e9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -28,7 +28,7 @@ export interface ActionButtonProperties extends ViewProperties { size?: number, autoInactive?: boolean, onPress?: () => void, - renderIcon?: (active: boolean) => React.ReactElement, + renderIcon?: (active: boolean) => React.ReactElement, backdrop?: boolean | object, degrees?: number, verticalOrientation?: 'up' | 'down', From 5f25552b7d0f8d6c7c33fe1a1e7b4ccdbd1a9d44 Mon Sep 17 00:00:00 2001 From: Shaw Date: Fri, 3 Jan 2020 22:29:58 +0800 Subject: [PATCH 70/74] Ignore example while publish (#326) ignore example folder in npm registry --- .npmignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..33a9488 --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +example From bbf5b199c1dd11c21dbca4ca581b7aab00c0a6e5 Mon Sep 17 00:00:00 2001 From: Luke Fanning Date: Fri, 3 Jan 2020 14:39:07 +0000 Subject: [PATCH 71/74] Added numberOfLines prop for text truncation (#312) feat: add numberOfLines prop to ActionButtonItem for text truncation --- ActionButtonItem.js | 10 +++++++--- README.md | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ActionButtonItem.js b/ActionButtonItem.js index 7475bff..c5ee780 100644 --- a/ActionButtonItem.js +++ b/ActionButtonItem.js @@ -34,7 +34,8 @@ export default class ActionButtonItem extends Component { useNativeFeedback: true, activeOpacity: DEFAULT_ACTIVE_OPACITY, fixNativeFeedbackRadius: false, - nativeFeedbackRippleColor: "rgba(255,255,255,0.75)" + nativeFeedbackRippleColor: "rgba(255,255,255,0.75)", + numberOfLines: 1, }; } @@ -44,7 +45,8 @@ export default class ActionButtonItem extends Component { useNativeFeedback: PropTypes.bool, fixNativeFeedbackRadius: PropTypes.bool, nativeFeedbackRippleColor: PropTypes.string, - activeOpacity: PropTypes.number + activeOpacity: PropTypes.number, + numberOfLines: PropTypes.number, }; } @@ -140,7 +142,8 @@ export default class ActionButtonItem extends Component { parentSize, size, position, - spaceBetween + spaceBetween, + numberOfLines, } = this.props; const offsetTop = Math.max(size / 2 - TEXT_HEIGHT / 2, 0); const positionStyles = { top: offsetTop }; @@ -169,6 +172,7 @@ export default class ActionButtonItem extends Component { {this.props.title} diff --git a/README.md b/README.md index 860f1e3..6402389 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ Take a look at [this gist](https://gist.github.com/mmazzarolo/cfd467436f9d110e94 | textContainerStyle | style | null | use this to set the textstyle of the button's item text container | textStyle | style | null | use this to set the textstyle of the button's item text | spaceBetween | number | 15 | use this to set the space between the Button and the text container +| numberOfLines | number | 1 | use this to set the number of lines on the button's item text | activeOpacity | number | 0.85 | activeOpacity props of TouchableOpacity | hideLabelShadow | boolean | same as hideShadow | use this to hide the button's label default elevation and boxShadow | shadowStyle | style | null | The custom shadow style you want to pass in the action button item From 8df917c94955f4b96ecbf6874f8da2547752f292 Mon Sep 17 00:00:00 2001 From: Igor Date: Fri, 3 Jan 2020 15:57:42 +0100 Subject: [PATCH 72/74] 3D Touch fix: Add "rejectResponderTermination" prop to Touchables (#267) fix: unresponsiveness of buttons on devices with 3d touch --- ActionButton.js | 2 ++ ActionButtonItem.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ActionButton.js b/ActionButton.js index b8306c2..7d344c8 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -200,6 +200,7 @@ export default class ActionButton extends Component { ]} > Date: Fri, 10 Jan 2020 16:51:10 -0500 Subject: [PATCH 73/74] Adaptation of Sibelius' changes --- ActionButton.js | 365 ++++++++++++++++++++++-------------------------- 1 file changed, 168 insertions(+), 197 deletions(-) diff --git a/ActionButton.js b/ActionButton.js index 7d344c8..ec1b9e3 100644 --- a/ActionButton.js +++ b/ActionButton.js @@ -1,11 +1,11 @@ -import React, { Component } from "react"; +import React, { Component, useState, useRef, useEffect } from "react"; import PropTypes from "prop-types"; import { StyleSheet, Text, View, Animated, - TouchableOpacity, + TouchableOpacity } from "react-native"; import ActionButtonItem from "./ActionButtonItem"; import { @@ -17,223 +17,160 @@ import { DEFAULT_ACTIVE_OPACITY } from "./shared"; -export default class ActionButton extends Component { - constructor(props) { - super(props); +const ActionButton = props => { + const [, setResetToken] = useState(props.resetToken); + const [active, setActive] = useState(props.active); + const anim = useRef(new Animated.Value(props.active ? 1 : 0)); + const timeout = useRef(null); + const mounted = useRef(false); - this.state = { - resetToken: props.resetToken, - active: props.active - }; - - this.anim = new Animated.Value(props.active ? 1 : 0); - this.timeout = null; - } - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - clearTimeout(this.timeout); - } + useEffect(() => { + mounted.current = true; - componentWillReceiveProps(nextProps) { - if (nextProps.resetToken !== this.state.resetToken) { - if (nextProps.active === false && this.state.active === true) { - if (this.props.onReset) this.props.onReset(); - Animated.spring(this.anim, { toValue: 0 }).start(); - setTimeout( - () => - this.setState({ active: false, resetToken: nextProps.resetToken }), - 250 - ); - return; - } + return () => { + mounted.current = false; + timeout.current && clearTimeout(timeout.current); + }; + }, []); - if (nextProps.active === true && this.state.active === false) { - Animated.spring(this.anim, { toValue: 1 }).start(); - this.setState({ active: true, resetToken: nextProps.resetToken }); - return; - } + useEffect(() => { + if (props.active) { + Animated.spring(anim.current, { toValue: 1 }).start(); + setActive(true); + setResetToken(props.resetToken); + } else { + props.onReset && props.onReset(); - this.setState({ - resetToken: nextProps.resetToken, - active: nextProps.active - }); + Animated.spring(anim.current, { toValue: 0 }).start(); + timeout.current = setTimeout(() => { + setActive(false); + setResetToken(props.resetToken); + }, 250); } - } + }, [props.resetToken, props.active]); ////////////////////// // STYLESHEET GETTERS ////////////////////// - getOrientation() { - return { alignItems: alignItemsMap[this.props.position] }; - } + const getOrientation = () => { + return { alignItems: alignItemsMap[props.position] }; + }; - getOffsetXY() { + const getOffsetXY = () => { return { - // paddingHorizontal: this.props.offsetX, - paddingVertical: this.props.offsetY + // paddingHorizontal: props.offsetX, + paddingVertical: props.offsetY }; - } + }; - getOverlayStyles() { + const getOverlayStyles = () => { return [ styles.overlay, { - elevation: this.props.elevation, - zIndex: this.props.zIndex, - justifyContent: this.props.verticalOrientation === "up" - ? "flex-end" - : "flex-start" + elevation: props.elevation, + zIndex: props.zIndex, + justifyContent: + props.verticalOrientation === "up" ? "flex-end" : "flex-start" } ]; - } - - ////////////////////// - // RENDER METHODS - ////////////////////// - - render() { - return ( - - - {this.props.backdrop} - - - {this.state.active && - !this.props.backgroundTappable && - this._renderTappableBackground()} - - {this.props.verticalOrientation === "up" && - this.props.children && - this._renderActions()} - {this._renderMainButton()} - {this.props.verticalOrientation === "down" && - this.props.children && - this._renderActions()} - - - ); - } + }; - _renderMainButton() { + const _renderMainButton = () => { const animatedViewStyle = { transform: [ { - scale: this.anim.interpolate({ + scale: anim.current.interpolate({ inputRange: [0, 1], - outputRange: [1, this.props.outRangeScale] + outputRange: [1, props.outRangeScale] }) }, { - rotate: this.anim.interpolate({ + rotate: anim.current.interpolate({ inputRange: [0, 1], - outputRange: ["0deg", this.props.degrees + "deg"] + outputRange: ["0deg", props.degrees + "deg"] }) } ] }; const wrapperStyle = { - backgroundColor: this.anim.interpolate({ + backgroundColor: anim.current.interpolate({ inputRange: [0, 1], - outputRange: [ - this.props.buttonColor, - this.props.btnOutRange || this.props.buttonColor - ] + outputRange: [props.buttonColor, props.btnOutRange || props.buttonColor] }), - width: this.props.size, - height: this.props.size, - borderRadius: this.props.size / 2 + width: props.size, + height: props.size, + borderRadius: props.size / 2 }; const buttonStyle = { - width: this.props.size, - height: this.props.size, - borderRadius: this.props.size / 2, + width: props.size, + height: props.size, + borderRadius: props.size / 2, alignItems: "center", justifyContent: "center" }; - const Touchable = getTouchableComponent(this.props.useNativeFeedback); - const parentStyle = isAndroid && - this.props.fixNativeFeedbackRadius - ? { - right: this.props.offsetX, - zIndex: this.props.zIndex, - borderRadius: this.props.size / 2, - width: this.props.size - } - : { marginHorizontal: this.props.offsetX, zIndex: this.props.zIndex }; + const Touchable = getTouchableComponent(props.useNativeFeedback); + const parentStyle = + isAndroid && props.fixNativeFeedbackRadius + ? { + right: props.offsetX, + zIndex: props.zIndex, + borderRadius: props.size / 2, + width: props.size + } + : { marginHorizontal: props.offsetX, zIndex: props.zIndex }; return ( - { - this.props.onPress(); - if (this.props.children) this.animateButton(); + props.onPress(); + if (props.children) animateButton(); }} - onPressIn={this.props.onPressIn} - onPressOut={this.props.onPressOut} + onPressIn={props.onPressIn} + onPressOut={props.onPressOut} > - + - {this._renderButtonIcon()} + {_renderButtonIcon()} ); - } - - _renderButtonIcon() { - const { icon, renderIcon, btnOutRangeTxt, buttonTextStyle, buttonText } = this.props; - if (renderIcon) return renderIcon(this.state.active); + }; + + const _renderButtonIcon = () => { + const { + icon, + renderIcon, + btnOutRangeTxt, + buttonTextStyle, + buttonText + } = props; + if (renderIcon) return renderIcon(active); if (icon) { - console.warn('react-native-action-button: The `icon` prop is deprecated! Use `renderIcon` instead.'); + console.warn( + "react-native-action-button: The `icon` prop is deprecated! Use `renderIcon` instead." + ); return icon; } @@ -245,7 +182,7 @@ export default class ActionButton extends Component { styles.btnText, buttonTextStyle, { - color: this.anim.interpolate({ + color: anim.current.interpolate({ inputRange: [0, 1], outputRange: [textColor, btnOutRangeTxt || textColor] }) @@ -255,26 +192,26 @@ export default class ActionButton extends Component { {buttonText} ); - } + }; - _renderActions() { - const { children, verticalOrientation } = this.props; + const _renderActions = () => { + const { children, verticalOrientation } = props; - if (!this.state.active) return null; + if (!active) return null; let actionButtons = !Array.isArray(children) ? [children] : children; - actionButtons = actionButtons.filter( actionButton => (typeof actionButton == 'object') ) + actionButtons = actionButtons.filter( + actionButton => typeof actionButton == "object" + ); const actionStyle = { flex: 1, alignSelf: "stretch", // backgroundColor: 'purple', justifyContent: verticalOrientation === "up" ? "flex-end" : "flex-start", - paddingTop: this.props.verticalOrientation === "down" - ? this.props.spacing - : 0, - zIndex: this.props.zIndex + paddingTop: props.verticalOrientation === "down" ? props.spacing : 0, + zIndex: props.zIndex }; return ( @@ -282,14 +219,14 @@ export default class ActionButton extends Component { {actionButtons.map((ActionButton, idx) => ( { - if (this.props.autoInactive) { - this.timeout = setTimeout(this.reset.bind(this), 200); + if (props.autoInactive) { + timeout.current = setTimeout(reset, 200); } ActionButton.props.onPress(); }} @@ -297,51 +234,84 @@ export default class ActionButton extends Component { ))} ); - } + }; - _renderTappableBackground() { + const _renderTappableBackground = () => { return ( ); - } + }; ////////////////////// // Animation Methods ////////////////////// - animateButton(animate = true) { - if (this.state.active) return this.reset(); + const animateButton = (animate = true) => { + if (active) return reset(animate); if (animate) { - Animated.spring(this.anim, { toValue: 1 }).start(); + Animated.spring(anim.current, { toValue: 1 }).start(); } else { - this.anim.setValue(1); + anim.current.setValue(1); } - this.setState({ active: true, resetToken: this.state.resetToken }); - } + setActive(true); + }; - reset(animate = true) { - if (this.props.onReset) this.props.onReset(); + const reset = (animate = true) => { + if (props.onReset) props.onReset(); if (animate) { - Animated.spring(this.anim, { toValue: 0 }).start(); + Animated.spring(anim.current, { toValue: 0 }).start(); } else { - this.anim.setValue(0); + anim.current.setValue(0); } - setTimeout(() => { - if (this.mounted) { - this.setState({ active: false, resetToken: this.state.resetToken }); + timeout.current = setTimeout(() => { + if (mounted.current) { + setActive(false); } }, 250); - } -} + }; + + return ( + + + {props.backdrop} + + + {active && !props.backgroundTappable && _renderTappableBackground()} + + {props.verticalOrientation === "up" && + props.children && + _renderActions()} + {_renderMainButton()} + {props.verticalOrientation === "down" && + props.children && + _renderActions()} + + + ); +}; ActionButton.Item = ActionButtonItem; @@ -437,3 +407,4 @@ const styles = StyleSheet.create({ backgroundColor: "transparent" } }); +export default ActionButton; From ad8c7e5d482296ab4f92aebcf9dcfd28481d7e15 Mon Sep 17 00:00:00 2001 From: Sibelius Seraphini Date: Mon, 13 Jan 2020 14:50:17 -0300 Subject: [PATCH 74/74] feat(bump): new version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5cd1443..75a66d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-action-button", - "version": "2.8.5", + "version": "2.9.0", "description": "customizable multi-action-button component for react-native", "main": "ActionButton.js", "scripts": {