diff options
| author | anderklander <anderklander@gmail.com> | 2018-02-06 13:06:42 +0100 |
|---|---|---|
| committer | anderklander <anderklander@gmail.com> | 2018-02-15 15:58:38 +0100 |
| commit | 6efe0f6a44512c2a1ac51109ea498f1df7960ee5 (patch) | |
| tree | b182bdb0168ff3f833ba5a657bdef18452c13ccb | |
| parent | c6d4b3a2370fa6feeaaf33f0425127753e93039e (diff) | |
| download | mullvadvpn-6efe0f6a44512c2a1ac51109ea498f1df7960ee5.tar.xz mullvadvpn-6efe0f6a44512c2a1ac51109ea498f1df7960ee5.zip | |
Common button component
| -rw-r--r-- | app/components/Settings.js | 103 | ||||
| -rw-r--r-- | app/components/SettingsStyles.js | 27 | ||||
| -rw-r--r-- | app/components/styled/CellButton.js | 95 | ||||
| -rw-r--r-- | app/components/styled/index.js | 4 | ||||
| -rw-r--r-- | test/components/Settings.spec.js | 6 |
5 files changed, 155 insertions, 80 deletions
diff --git a/app/components/Settings.js b/app/components/Settings.js index 4022054acd..7d27371ad4 100644 --- a/app/components/Settings.js +++ b/app/components/Settings.js @@ -2,7 +2,7 @@ import moment from 'moment'; import React from 'react'; import { Component, Text, View } from 'reactxp'; -import { Button } from './styled'; +import { Button, CellButton } from './styled'; import { Layout, Container, Header } from './Layout'; import CustomScrollbars from './CustomScrollbars'; import styles from './SettingsStyles'; @@ -81,40 +81,48 @@ export default class Settings extends Component { return <View> <View style={styles.settings_account} testName='settings__account'> - <Button onPress={ this.props.onViewAccount } testName='settings__view_account'> - <View style={styles.settings__cell}> - <Text style={styles.settings__cell_label}>Account</Text> - {isOutOfTime ? ( - <Text style={styles.settings__account_paid_until_label__error} testName='settings__account_paid_until_label'>OUT OF TIME</Text> - ) : ( - <Text style={styles.settings__cell_subtext} testName='settings__account_paid_until_label'>{formattedExpiry}</Text> - )} - <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/> - </View> - </Button> + {isOutOfTime ? ( + <CellButton onPress={ this.props.onViewAccount } + text='Account' + testName='settings__account_paid_until_label' + subtext='OUT OF TIME' + subtextStyle={ styles.settings__account_paid_until_label__error } + icon='icon-chevron' + iconStyle={styles.settings__icon_chevron} + tintColor='currentColor'/> + ) : ( + <CellButton onPress={ this.props.onViewAccount } + text='Account' + testName='settings__account_paid_until_label' + subtext={ formattedExpiry } + subtextStyle={ styles.settings__account_paid_until_label } + icon='icon-chevron' + iconStyle={styles.settings__icon_chevron} + tintColor='currentColor'/> + )} </View> - <ButtonCell onPress={ this.props.onViewPreferences } testName='settings__preferences'> - <Text style={styles.settings__cell_label}>Preferences</Text> - <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor' /> - </ButtonCell> - - <ButtonCell onPress={ this.props.onViewAdvancedSettings } testName='settings__advanced'> - <Text style={styles.settings__cell_label}>Advanced</Text> - <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/> - </ButtonCell> + <CellButton onPress={ this.props.onViewPreferences } + testName='settings__preferences' + text='Preferences' + icon='icon-chevron' + tintColor='currentColor'/> + <CellButton onPress={ this.props.onViewAdvancedSettings } + testName='settings__advanced' + text='Advanced' + icon='icon-chevron' + tintColor='currentColor'/> </View>; } _renderMiddleButtons() { - return <View> - <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'download') } testName='settings__version'> - <Text style={styles.settings__cell_label}>App version</Text> - <Text style={styles.settings__cell_subtext}>{this._formattedVersion()}</Text> - <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/> - </ButtonCell> - </View>; + return <CellButton onPress={ this.props.onExternalLink.bind(this, 'download') } + testName='settings__version' + text='App version' + subtext={this._formattedVersion()} + icon='icon-extLink' + tintColor='currentColor'/>; } _formattedVersion() { @@ -128,20 +136,24 @@ export default class Settings extends Component { _renderBottomButtons() { return <View> - <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'faq') } testName='settings__external_link'> - <Text style={styles.settings__cell_label}>FAQs</Text> - <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/> - </ButtonCell> + <CellButton onPress={ this.props.onExternalLink.bind(this, 'faq') } + testName='settings__external_link' + text='FAQs' + icon='icon-extLink' + tintColor='currentColor'/> - <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'guides') } testName='settings__external_link'> - <Text style={styles.settings__cell_label}>Guides</Text> - <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/> - </ButtonCell> + <CellButton onPress={ this.props.onExternalLink.bind(this, 'guides') } + testName='settings__external_link' + text='Guides' + icon='icon-extLink' + tintColor='currentColor'/> - <ButtonCell onPress={ this.props.onViewSupport } testName='settings__view_support'> - <Text style={styles.settings__cell_label}>Contact support</Text> - <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/> - </ButtonCell> + <CellButton onPress={ this.props.onViewSupport } + testName='settings__view_support' + text='Contact support' + icon='icon-chevron' + iconStyle={styles.settings__icon_chevron} + tintColor='currentColor'/> </View>; } @@ -152,13 +164,4 @@ export default class Settings extends Component { </Button> </View>; } -} - -function ButtonCell(props) { - const { children, ...rest } = props; - return <Button { ...rest } > - <View style={styles.settings__cell}> - { children } - </View> - </Button>; -} +}
\ No newline at end of file diff --git a/app/components/SettingsStyles.js b/app/components/SettingsStyles.js index d37703a8fe..734d73ad90 100644 --- a/app/components/SettingsStyles.js +++ b/app/components/SettingsStyles.js @@ -44,19 +44,7 @@ export default Object.assign(createViewStyles({ flex: 0, opacity: 0.6, }, - settings__cell:{ - backgroundColor: 'rgba(41,71,115,1)', - paddingTop: 15, - paddingBottom: 15, - paddingLeft: 24, - paddingRight: 24, - marginBottom: 1, - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between' - }, - settings__cell_disclosure:{ + settings__icon_chevron:{ marginLeft: 8, color: 'rgba(255, 255, 255, 0.8)', width: 7, @@ -66,19 +54,6 @@ export default Object.assign(createViewStyles({ height: 24, flex: 0 }, - settings__cell__active_hover:{ - backgroundColor: 'rgba(41,71,115,0.9)' - }, - settings__cell_icon:{ - marginLeft: 8, - width: 16, - height: 16, - flexGrow: 0, - flexShrink: 0, - flexBasis: 'auto', - alignItems: 'flex-end', - color: 'rgba(255, 255, 255, 0.8)', - }, settings__footer_button:{ backgroundColor: 'rgba(208,2,27,1)', paddingTop: 7, diff --git a/app/components/styled/CellButton.js b/app/components/styled/CellButton.js new file mode 100644 index 0000000000..b74f0cdfb0 --- /dev/null +++ b/app/components/styled/CellButton.js @@ -0,0 +1,95 @@ +// @flow +import React from 'react'; +import { Text, Component } from 'reactxp'; +import { Button } from './Button'; +import Img from '../Img'; + +import { createViewStyles, createTextStyles } from '../../lib/styles'; + +const styles = { + ...createViewStyles({ + cell:{ + backgroundColor: 'rgba(41,71,115,1)', + paddingTop: 15, + paddingBottom: 15, + paddingLeft: 24, + paddingRight: 24, + marginBottom: 1, + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between' + }, + hover:{ + backgroundColor: 'rgba(41,71,115,0.9)' + }, + icon:{ + marginLeft: 8, + width: 16, + height: 16, + flexGrow: 0, + flexShrink: 0, + flexBasis: 'auto', + alignItems: 'flex-end', + color: 'rgba(255, 255, 255, 0.8)', + }, + }), + ...createTextStyles({ + label:{ + fontFamily: 'DINPro', + fontSize: 20, + fontWeight: '900', + lineHeight: 26, + color: '#FFFFFF', + flexGrow: 1, + flexShrink: 0, + flexBasis: 'auto', + }, + subtext:{ + fontFamily: 'Open Sans', + fontSize: 13, + fontWeight: '800', + color: 'rgba(255, 255, 255, 0.8)', + flexGrow: 0, + textAlign: 'right', + }, + }) +}; + +export default class CellButton extends Component { + props: { + icon?: string, + iconStyle?: string, + hoverStyle?: string, + subtextStyle?: string, + text: string, + subtext?: string, + tintColor?: string, + onPress?: () => void, + style?: string + }; + + state = { hovered: false }; + + render() { + const { style, tintColor, hoverStyle, text, subtext, subtextStyle, icon, iconStyle, onPress, ...otherProps } = this.props; + + return ( + <Button style={[ styles.cell, style, this.state.hovered ? [styles.hover, hoverStyle] : null ]} + onPress={ onPress } + onHoverStart={() => this.setState({ hovered: true })} + onHoverEnd={() => this.setState({ hovered: false })} + {...otherProps}> + + <Text style={ styles.label }>{ text }</Text> + + { subtext ? <Text style={[ styles.subtext, subtextStyle ]}>{ subtext }</Text> : null } + + <Img style={[ styles.icon, iconStyle ]} + source={ icon } + tintColor={ tintColor }/> + + </Button> + ); + } +} diff --git a/app/components/styled/index.js b/app/components/styled/index.js index 6699594f18..0aeddca65e 100644 --- a/app/components/styled/index.js +++ b/app/components/styled/index.js @@ -1,7 +1,9 @@ // @flow import { Button } from './Button'; +import CellButton from './CellButton'; export { - Button + Button, + CellButton, }; diff --git a/test/components/Settings.spec.js b/test/components/Settings.spec.js index fc6b73f17c..d8d30ab4df 100644 --- a/test/components/Settings.spec.js +++ b/test/components/Settings.spec.js @@ -109,13 +109,13 @@ describe('components/Settings', () => { it('should show out-of-time message for unpaid account', () => { const props = makeProps(unpaidAccountState, settingsState); const component = getComponent(render(props), 'settings__account_paid_until_label'); - expect(component.children().text()).to.equal('OUT OF TIME'); + expect(component.prop('subtext')).to.equal('OUT OF TIME'); }); it('should hide out-of-time message for paid account', () => { const props = makeProps(loggedInAccountState, settingsState); const component = getComponent(render(props), 'settings__account_paid_until_label'); - expect(component.children().text()).not.to.equal('OUT OF TIME'); + expect(component.prop('subtext')).not.to.equal('OUT OF TIME'); }); it('should call close callback', (done) => { @@ -138,7 +138,7 @@ describe('components/Settings', () => { const props = makeProps(loggedInAccountState, settingsState, { onViewAccount: () => done() }); - const component = getComponent(render(props), 'settings__view_account'); + const component = getComponent(render(props), 'settings__account_paid_until_label'); click(component); }); |
