diff --git a/example/src/ButtonsExample.js b/example/src/ButtonsExample.js new file mode 100644 index 0000000..a719fae --- /dev/null +++ b/example/src/ButtonsExample.js @@ -0,0 +1,60 @@ +/* @flow */ + +import React, { Component } from 'react'; +import { + View, + StyleSheet, +} from 'react-native'; +import { + Colors, + Button, +} from 'react-native-paper'; + +export default class ButtonsExample extends Component { + + static title = 'Button'; + + render() { + return ( + + + + + + + + + + + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + backgroundColor: Colors.white, + padding: 8, + }, + + row: { + flexDirection: 'row', + alignItems: 'center', + }, + + button: { + backgroundColor: Colors.pink500, + }, +}); diff --git a/example/src/ExampleList.js b/example/src/ExampleList.js index 503c8b9..7f11727 100644 --- a/example/src/ExampleList.js +++ b/example/src/ExampleList.js @@ -10,14 +10,16 @@ import { StyleSheet, } from 'react-native'; import { Colors, TouchableRipple } from 'react-native-paper'; -import RipplesExample from './RipplesExample'; +import RippleExample from './RippleExample'; import PaperExample from './PaperExample'; -import TextExamples from './TextExamples'; +import TextExample from './TextExample'; +import ButtonsExample from './ButtonsExample'; export const examples = { - ripples: RipplesExample, + ripple: RippleExample, paper: PaperExample, - text: TextExamples, + text: TextExample, + button: ButtonsExample, }; export default class ExampleList extends Component { diff --git a/example/src/RipplesExample.js b/example/src/RippleExample.js similarity index 67% rename from example/src/RipplesExample.js rename to example/src/RippleExample.js index d3eb0e1..67ffb3b 100644 --- a/example/src/RipplesExample.js +++ b/example/src/RippleExample.js @@ -2,7 +2,7 @@ import { Component } from 'react'; -export default class RipplesExample extends Component { +export default class RippleExample extends Component { static title = 'Ripples'; diff --git a/example/src/TextExamples.js b/example/src/TextExample.js similarity index 93% rename from example/src/TextExamples.js rename to example/src/TextExample.js index 766a370..88dbd44 100644 --- a/example/src/TextExamples.js +++ b/example/src/TextExample.js @@ -13,7 +13,7 @@ import { Title, } from 'react-native-paper'; -export default class TextExamples extends Component { +export default class TextExample extends Component { static title = 'Typography'; diff --git a/index.js b/index.js index 97ef772..7ec3cba 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,8 @@ export * as Colors from './src/styles/colors'; export { default as Paper } from './src/components/Paper'; export { default as TouchableRipple } from './src/components/TouchableRipple'; +export { default as Button } from './src/components/Button'; + export { default as Caption } from './src/components/Typography/Caption'; export { default as Headline } from './src/components/Typography/Headline'; export { default as Paragraph } from './src/components/Typography/Paragraph'; diff --git a/src/components/Button.js b/src/components/Button.js new file mode 100644 index 0000000..3fe7c83 --- /dev/null +++ b/src/components/Button.js @@ -0,0 +1,139 @@ +/* @flow */ + +import color from 'color'; +import React, { + Component, + PropTypes, +} from 'react'; +import { + Animated, + View, + StyleSheet, +} from 'react-native'; +import Paper from './Paper'; +import Text from './Typography/Text'; +import TouchableRipple from './TouchableRipple'; +import { black, white } from '../styles/colors'; +import withTheme from '../core/withTheme'; +import type { Theme } from '../types/Theme'; + +const AnimatedPaper = Animated.createAnimatedComponent(Paper); + +type DefaultProps = { + raised: boolean; + primary: boolean; + roundness: number; +} + +type Props = { + raised?: boolean; + primary?: boolean; + dark?: boolean; + roundness?: number; + children?: string; + onPress?: Function; + style?: any; + theme: Theme; +} + +type State = { + elevation: Animated.Value; +} + +class Button extends Component { + static propTypes = { + raised: PropTypes.bool, + primary: PropTypes.bool, + dark: PropTypes.bool, + roundness: PropTypes.number, + children: PropTypes.string.isRequired, + onPress: PropTypes.func, + style: View.propTypes.style, + theme: PropTypes.object.isRequired, + }; + + static defaultProps = { + raised: false, + primary: false, + roundness: 2, + }; + + constructor(props: Props) { + super(props); + this.state = { + elevation: new Animated.Value(props.raised ? 2 : 0), + }; + } + + state: State; + + _handlePressIn = () => { + if (this.props.raised) { + Animated.timing(this.state.elevation, { + toValue: 6, + duration: 200, + }).start(); + } + }; + + _handlePressOut = () => { + if (this.props.raised) { + Animated.timing(this.state.elevation, { + toValue: 2, + duration: 200, + }).start(); + } + }; + + render() { + const { + primary, + dark, + roundness, + children, + onPress, + style, + theme, + } = this.props; + const { colors } = theme; + const backgroundColor = primary ? colors.primary : white; + const fontFamily = theme.fonts.medium; + const isDark = typeof dark === 'boolean' ? dark : !color(backgroundColor).light(); + const textColor = isDark ? white : black; + const rippleColor = color(textColor).alpha(0.32).rgbaString(); + const buttonStyle = { backgroundColor, borderRadius: roundness }; + const touchableStyle = { borderRadius: roundness }; + + return ( + + + + {children ? children.toUpperCase() : ''} + + + + ); + } +} + +const styles = StyleSheet.create({ + button: { + margin: 8, + minWidth: 88, + }, + label: { + textAlign: 'center', + marginVertical: 9, + marginHorizontal: 16, + }, +}); + +export default withTheme(Button); diff --git a/src/components/Paper.js b/src/components/Paper.js index 52ec4d3..504233f 100644 --- a/src/components/Paper.js +++ b/src/components/Paper.js @@ -28,7 +28,7 @@ export default class Paper extends Component { const { children, elevation } = this.props; return ( - + {children} ); diff --git a/src/components/TouchableRipple/TouchableRipple.android.js b/src/components/TouchableRipple/TouchableRipple.android.js index aacc033..3b87652 100644 --- a/src/components/TouchableRipple/TouchableRipple.android.js +++ b/src/components/TouchableRipple/TouchableRipple.android.js @@ -12,7 +12,10 @@ import { type Props = { borderless: boolean; + delayPressIn?: number; onPress?: ?Function; + onPressIn?: ?Function; + onPressOut?: ?Function; rippleColor?: string; children?: any; style?: any; @@ -27,7 +30,10 @@ export default class TouchableRipple extends Component= 21 ? TouchableNativeFeedback.Ripple(rippleColor, borderless) : TouchableNativeFeedback.SelectableBackground()} diff --git a/src/components/TouchableRipple/TouchableRipple.js b/src/components/TouchableRipple/TouchableRipple.js index 110e3dd..353561d 100644 --- a/src/components/TouchableRipple/TouchableRipple.js +++ b/src/components/TouchableRipple/TouchableRipple.js @@ -11,7 +11,10 @@ import { type Props = { borderless: boolean; + delayPressIn?: number; onPress?: ?Function; + onPressIn?: ?Function; + onPressOut?: ?Function; rippleColor?: string; children?: any; style?: any; @@ -25,7 +28,10 @@ export default class TouchableRipple extends Component {children} diff --git a/src/components/Typography/Text.js b/src/components/Typography/Text.js index d4491db..58ab4d7 100644 --- a/src/components/Typography/Text.js +++ b/src/components/Typography/Text.js @@ -19,6 +19,12 @@ class Text extends Component { style: NativeText.propTypes.style, }; + _root: any; + + setNativeProps(...args) { + return this._root.setNativeProps(...args); + } + render() { const { style, @@ -28,6 +34,7 @@ class Text extends Component { return ( (this._root = c)} style={[ { fontFamily: theme.fonts.regular, color: theme.colors.text }, style ]} /> ); diff --git a/src/core/withTheme.js b/src/core/withTheme.js index 6d44a06..fc2fa47 100644 --- a/src/core/withTheme.js +++ b/src/core/withTheme.js @@ -8,13 +8,25 @@ import { theme } from './ThemeProvider'; export default function withTheme(Comp: ReactClass): ReactClass { class ThemedComponent extends Component { - static displayName = `Themed${Comp.displayName || Comp.name}`; + static displayName = `withTheme(${Comp.displayName || Comp.name})`; static contextTypes = { [theme]: PropTypes.object, }; + _root: any; + + setNativeProps(...args) { + return this._root.setNativeProps(...args); + } + render() { - return ; + return ( + (this._root = c)} + theme={this.context[theme]} + {...this.props} + /> + ); } }