diff --git a/Button.js b/Button.js deleted file mode 100644 index fb7cf46..0000000 --- a/Button.js +++ /dev/null @@ -1,115 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { - StyleSheet, - Text, - TouchableOpacity, - View, - ViewPropTypes, -} from 'react-native'; - -import coalesceNonElementChildren from './coalesceNonElementChildren'; - -const systemButtonOpacity = 0.2; - -export default class Button extends Component { - static propTypes = { - ...TouchableOpacity.propTypes, - accessibilityLabel: PropTypes.string, - allowFontScaling: Text.propTypes.allowFontScaling, - containerStyle: ViewPropTypes.style, - disabledContainerStyle: ViewPropTypes.style, - disabled: PropTypes.bool, - style: Text.propTypes.style, - styleDisabled: Text.propTypes.style, - childGroupStyle: ViewPropTypes.style, - }; - - render() { - let touchableProps = { - activeOpacity: this._computeActiveOpacity(), - }; - let containerStyle = [ - this.props.containerStyle, - this.props.disabled ? this.props.disabledContainerStyle : null - ]; - - if (!this.props.disabled) { - touchableProps.onPress = this.props.onPress; - touchableProps.onPressIn = this.props.onPressIn; - touchableProps.onPressOut = this.props.onPressOut; - touchableProps.onLongPress = this.props.onLongPress; - touchableProps.delayPressIn = this.props.delayPressIn; - touchableProps.delayPressOut = this.props.delayPressOut; - touchableProps.delayLongPress = this.props.delayLongPress; - } - - return ( - - {this._renderGroupedChildren()} - - ); - } - - _renderGroupedChildren() { - let { disabled } = this.props; - let style = [ - styles.text, - disabled ? styles.disabledText : null, - this.props.style, - disabled ? this.props.styleDisabled : null, - ]; - let childGroupStyle = [ - styles.group, - this.props.childGroupStyle, - ]; - - let children = coalesceNonElementChildren(this.props.children, (children, index) => { - return ( - - {children} - - ); - }); - - switch (children.length) { - case 0: - return null; - case 1: - return children[0]; - default: - return {children}; - } - } - - _computeActiveOpacity() { - if (this.props.disabled) { - return 1; - } - return this.props.activeOpacity != null ? - this.props.activeOpacity : - systemButtonOpacity; - } -}; - -const styles = StyleSheet.create({ - text: { - color: '#007aff', - fontSize: 17, - fontWeight: '500', - textAlign: 'center', - }, - disabledText: { - color: '#dcdcdc', - }, - group: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }, -}); diff --git a/Button.tsx b/Button.tsx new file mode 100644 index 0000000..e4c2bce --- /dev/null +++ b/Button.tsx @@ -0,0 +1,137 @@ +import React from 'react'; +import { + StyleSheet, + Text, + TouchableOpacity, + View, + ViewStyle, + StyleProp, + TextStyle, + TouchableOpacityProps +} from 'react-native'; + +import coalesceNonElementChildren from './coalesceNonElementChildren'; + +const systemButtonOpacity = 0.2; + +interface propTypes extends TouchableOpacityProps { + accessibilityLabel?: string, + textID?: string, + allowFontScaling?: boolean, + disabled?: boolean, + containerStyle?: StyleProp, + disabledContainerStyle?: StyleProp, + style?: StyleProp, + styleDisabled?: StyleProp, + childGroupStyle?: StyleProp, + children: React.ReactChild +} + + +export default function Button({ + disabled, + activeOpacity, + style, + styleDisabled, + childGroupStyle, + children, + allowFontScaling, + containerStyle, + disabledContainerStyle, + onPress, + onPressIn, + onPressOut, + onLongPress, + delayPressIn, + delayPressOut, + delayLongPress, + testID, + accessibilityLabel + }: propTypes) { + function _computeActiveOpacity() { + if (disabled) { + return 1; + } + return activeOpacity != null ? + activeOpacity : + systemButtonOpacity; + } + + function _renderGroupedChildren() { + let styleRenderGroup = [ + styles.text, + disabled ? styles.disabledText : null, + style, + disabled ? styleDisabled : null, + ]; + let childGroupStyleCustom = [ + styles.group, + childGroupStyle, + ]; + const childrenCustom = coalesceNonElementChildren(children, (children: React.ReactNode, index: string | number | undefined) => { + return ( + + {childrenCustom} + + ); + }); + + switch (childrenCustom.length) { + case 0: + return null; + case 1: + return childrenCustom[0]; + default: + return {childrenCustom}; + } + } + + + const touchableProps: TouchableOpacityProps = { + activeOpacity: _computeActiveOpacity(), + + }; + const containerStyleCustom = [ + containerStyle, + disabled ? disabledContainerStyle : null + ]; + + if (!disabled) { + touchableProps.onPress = onPress; + touchableProps.onPressIn = onPressIn; + touchableProps.onPressOut = onPressOut; + touchableProps.onLongPress = onLongPress; + touchableProps.delayPressIn = delayPressIn; + touchableProps.delayPressOut = delayPressOut; + touchableProps.delayLongPress = delayLongPress; + } + + return ( + + {_renderGroupedChildren()} + + ); +} + + +const styles = StyleSheet.create({ + text: { + color: '#007aff', + fontSize: 17, + fontWeight: '500', + textAlign: 'center', + }, + disabledText: { + color: '#dcdcdc', + }, + group: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, +}); diff --git a/coalesceNonElementChildren.js b/coalesceNonElementChildren.js index e5433c6..2ec5cc2 100644 --- a/coalesceNonElementChildren.js +++ b/coalesceNonElementChildren.js @@ -1,31 +1,30 @@ -import React, { Children } from 'react'; - +import React, {Children} from 'react' +// @ts-ignore export default function coalesceNonElementChildren(children, coalesceNodes) { - var coalescedChildren = []; + let coalescedChildren = []; + let contiguousNonElements: React.ReactText[] = []; + Children.forEach(children, (child: React.ReactChild) => { + if (!React.isValidElement(child)) { + contiguousNonElements.push(child); + return; + } - var contiguousNonElements = []; - Children.forEach(children, (child) => { - if (!React.isValidElement(child)) { - contiguousNonElements.push(child); - return; - } + if (contiguousNonElements.length) { + coalescedChildren.push( + coalesceNodes(contiguousNonElements, coalescedChildren.length) + ); + contiguousNonElements = []; + } + + coalescedChildren.push(child); + }); if (contiguousNonElements.length) { - coalescedChildren.push( - coalesceNodes(contiguousNonElements, coalescedChildren.length) - ); - contiguousNonElements = []; + coalescedChildren.push( + coalesceNodes(contiguousNonElements, coalescedChildren.length) + ); } - coalescedChildren.push(child); - }); - - if (contiguousNonElements.length) { - coalescedChildren.push( - coalesceNodes(contiguousNonElements, coalescedChildren.length) - ); - } - - return coalescedChildren; + return coalescedChildren; } diff --git a/package.json b/package.json index 276d58f..93dd623 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "react-native": "*" }, "dependencies": { - "prop-types": "^15.5.10" + "typescript": "^3.5.3" + "@types/react": "^16.8.23", + "@types/react-native": "^0.60.0", } }