Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AmountInput and AssetSelectorButton, Keypad and Quick amounts components #3695

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions app/components/Base/Keypad/Keypad.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* eslint-disable react-native/no-color-literals */
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { storiesOf } from '@storybook/react-native';
import { select } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Text from '../Text';
import Keypad from '.';

const styles = StyleSheet.create({
customKeypad: {
backgroundColor: '#F8D5F9',
paddingVertical: 15,
width: 300,
},
customButtonStyle: {
borderWidth: 2,
paddingVertical: 2,
margin: 5,
borderRadius: 10,
backgroundColor: '#FFBCFC',
borderColor: '#F379F6',
},

customDigitTextStyle: {
fontSize: 25,
color: '#F124A3',
fontFamily: 'Helvetica',
},
});

storiesOf('Base / Keypad', module)
.addDecorator((getStory) => getStory())
.add('Default', () => {
const currency = select('Currency', ['usd', 'eur', 'jpy', 'clp'], 'usd');
const onKeypadChange = action('Keypad change');

return (
<SafeAreaView>
<Text big centered primary>
{`<Keypad>`} Component
</Text>
<Text primary>Example</Text>
<Keypad value="123" onChange={onKeypadChange} currency={currency} />
</SafeAreaView>
);
})
.add('Customized', () => {
const currency = select('Currency', ['usd', 'eur', 'jpy', 'clp'], 'usd');
const onKeypadChange = action('Keypad change');

return (
<SafeAreaView>
<Text big centered primary>
Custom {`<Keypad>`} Component
</Text>
<Text primary>Example</Text>
<Keypad
value="123"
onChange={onKeypadChange}
currency={currency}
style={styles.customKeypad}
digitButtonStyle={styles.customButtonStyle}
digitTextStyle={styles.customDigitTextStyle}
periodButtonStyle={styles.customButtonStyle}
periodTextStyle={styles.customDigitTextStyle}
deleteButtonStyle={styles.customButtonStyle}
deleteIcon={<FontAwesome name="cut" size={15} color="#F124A3" />}
/>
</SafeAreaView>
);
});
9 changes: 6 additions & 3 deletions app/components/Base/Keypad/__snapshots__/Keypad.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
exports[`Keypad component components should render correctly 1`] = `
<View
style={
Object {
"paddingHorizontal": 25,
}
Array [
Object {
"paddingHorizontal": 25,
},
undefined,
]
}
>
<KeypadRow>
Expand Down
41 changes: 33 additions & 8 deletions app/components/Base/Keypad/components.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import { View, StyleSheet, TouchableOpacity, ViewPropTypes } from 'react-native';
import IonicIcon from 'react-native-vector-icons/Ionicons';
import Device from '../../../util/device';

Expand Down Expand Up @@ -33,24 +33,49 @@ const styles = StyleSheet.create({
},
});

const KeypadContainer = (props) => <View style={styles.keypad} {...props} />;
const KeypadContainer = ({ style, ...props }) => <View style={[styles.keypad, style]} {...props} />;

KeypadContainer.propTypes = {
/**
* Custom style for digit buttons
*/
style: ViewPropTypes.style,
};

const KeypadRow = (props) => <View style={styles.keypadRow} {...props} />;
const KeypadButton = ({ children, ...props }) => (
<TouchableOpacity style={styles.keypadButton} {...props}>
<Text style={styles.keypadButtonText}>{children}</Text>

const KeypadButton = ({ style, textStyle, children, ...props }) => (
<TouchableOpacity style={[styles.keypadButton, style]} {...props}>
<Text style={[styles.keypadButtonText, textStyle]}>{children}</Text>
</TouchableOpacity>
);

KeypadButton.propTypes = {
children: PropTypes.node,
/**
* Custom style for digit buttons
*/
style: ViewPropTypes.style,
/**
* Custom style for digit text
*/
textStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};

const KeypadDeleteButton = (props) => (
<TouchableOpacity style={styles.keypadButton} {...props}>
<IonicIcon style={[styles.keypadButtonText, styles.deleteIcon]} name="md-arrow-back" />
const KeypadDeleteButton = ({ style, icon, ...props }) => (
<TouchableOpacity style={[styles.keypadButton, style]} {...props}>
{icon || <IonicIcon style={[styles.keypadButtonText, styles.deleteIcon]} name="md-arrow-back" />}
</TouchableOpacity>
);

KeypadDeleteButton.propTypes = {
/**
* Custom style for digit buttons
*/
style: ViewPropTypes.style,
icon: PropTypes.node,
};

const Keypad = KeypadContainer;
Keypad.Row = KeypadRow;
Keypad.Button = KeypadButton;
Expand Down
90 changes: 77 additions & 13 deletions app/components/Base/Keypad/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ import PropTypes from 'prop-types';
import Keypad from './components';
import { KEYS } from './constants';
import useCurrency from './useCurrency';
function KeypadComponent({ onChange, value, currency }) {
import { ViewPropTypes } from 'react-native';
function KeypadComponent({
onChange,
value,
currency,
style,
digitButtonStyle,
digitTextStyle,
periodButtonStyle,
periodTextStyle,
deleteButtonStyle,
deleteIcon,
}) {
const { handler, decimalSeparator } = useCurrency(currency);
const handleKeypadPress = useCallback(
(pressedKey) => {
Expand All @@ -30,26 +42,50 @@ function KeypadComponent({ onChange, value, currency }) {
const handleKeypadLongPressBack = useCallback(() => handleKeypadPress(KEYS.INITIAL), [handleKeypadPress]);

return (
<Keypad>
<Keypad style={style}>
<Keypad.Row>
<Keypad.Button onPress={handleKeypadPress1}>1</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress2}>2</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress3}>3</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress1}>
1
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress2}>
2
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress3}>
3
</Keypad.Button>
</Keypad.Row>
<Keypad.Row>
<Keypad.Button onPress={handleKeypadPress4}>4</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress5}>5</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress6}>6</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress4}>
4
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress5}>
5
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress6}>
6
</Keypad.Button>
</Keypad.Row>
<Keypad.Row>
<Keypad.Button onPress={handleKeypadPress7}>7</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress8}>8</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress9}>9</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress7}>
7
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress8}>
8
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress9}>
9
</Keypad.Button>
</Keypad.Row>
<Keypad.Row>
<Keypad.Button onPress={handleKeypadPressPeriod}>{decimalSeparator}</Keypad.Button>
<Keypad.Button onPress={handleKeypadPress0}>0</Keypad.Button>
<Keypad.Button style={periodButtonStyle} textStyle={periodTextStyle} onPress={handleKeypadPressPeriod}>
{decimalSeparator}
</Keypad.Button>
<Keypad.Button style={digitButtonStyle} textStyle={digitTextStyle} onPress={handleKeypadPress0}>
0
</Keypad.Button>
<Keypad.DeleteButton
style={deleteButtonStyle}
icon={deleteIcon}
onPress={handleKeypadPressBack}
onLongPress={handleKeypadLongPressBack}
delayLongPress={500}
Expand All @@ -72,6 +108,34 @@ KeypadComponent.propTypes = {
* Current value used to create new value when a key is pressed.
*/
value: PropTypes.string,
/**
* Custom style for container
*/
style: ViewPropTypes.style,
/**
* Custom style for digit buttons
*/
digitButtonStyle: ViewPropTypes.style,
/**
* Custom style for digit text
*/
digitTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
/**
* Custom style for period button
*/
periodButtonStyle: ViewPropTypes.style,
/**
* Custom style for period text
*/
periodTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
/**
* Custom style for delete button
*/
deleteButtonStyle: ViewPropTypes.style,
/**
* Custom icon for delete button
*/
deleteIcon: PropTypes.node,
};

export { KEYS };
Expand Down
2 changes: 1 addition & 1 deletion app/components/Base/ListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ const styles = StyleSheet.create({
icon: {
flexDirection: 'row',
alignItems: 'center',
marginRight: 15,
},
body: {
flex: 1,
marginLeft: 15,
},
amounts: {
flex: 0.6,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { SafeAreaView } from 'react-native';

import { storiesOf } from '@storybook/react-native';

import { action } from '@storybook/addon-actions';
import { text, boolean } from '@storybook/addon-knobs';

import AmountInput from './AmountInput';
import Text from '../../../Base/Text';

storiesOf('FiatOnRamp / AmountInput', module)
.addDecorator((getStory) => getStory())
.add('Default', () => {
const highlighted = boolean('Highlighted', false);
const label = text('Box label', 'Amount');
const currencySymbol = text('Currency Symbol', '$');
const currencyCode = text('Currency Code', 'USD');
const amount = text('Amount', '123');
const onAmountInputPress = action('AmountInput pressed');
const onCurrencyPress = action('Currency pressed');

return (
<SafeAreaView>
<Text big centered primary>
{`<AmountInput>`} Component
</Text>
<Text primary>Example</Text>

<AmountInput
highlighted={highlighted}
label={label}
currencySymbol={currencySymbol}
amount={amount}
currencyCode={currencyCode}
onPress={onAmountInputPress}
onCurrencyPress={onCurrencyPress}
/>
</SafeAreaView>
);
});
63 changes: 63 additions & 0 deletions app/components/UI/FiatOnRampAggregator/components/AmountInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';
import Box from './Box';
import BaseListItem from '../../../Base/ListItem';
import CustomText from '../../../Base/Text';

import CurrencyChevron from './CurrencyChevron';

// TODO: Convert into typescript and correctly type optionals
const Text = CustomText as any;
const ListItem = BaseListItem as any;

const styles = StyleSheet.create({
amount: {
fontSize: 24,
},
chevron: {
flex: 0,
marginLeft: 8,
},
});

interface Props {
label?: string;
currencySymbol?: string;
amount: string;
currencyCode: string;
highlighted?: boolean;
onPress?: () => any;
onCurrencyPress?: () => any;
}

const AmountInput: React.FC<Props> = ({
label,
currencySymbol,
amount,
currencyCode,
highlighted,
onPress,
onCurrencyPress,
}: Props) => (
<Box label={label} onPress={onPress} highlighted={highlighted}>
<ListItem.Content>
<ListItem.Body>
<Text black bold style={styles.amount} numberOfLines={1} adjustsFontSizeToFit>
{currencySymbol || ''}
{amount}
</Text>
</ListItem.Body>
<ListItem.Amounts style={styles.chevron}>
<TouchableOpacity
disabled={!onCurrencyPress}
onPress={onCurrencyPress}
hitSlop={{ top: 20, left: 20, right: 20, bottom: 20 }}
>
<CurrencyChevron currency={currencyCode} />
</TouchableOpacity>
</ListItem.Amounts>
</ListItem.Content>
</Box>
);

export default AmountInput;
Loading