feat: enhance Icon component (#125)

This commit is contained in:
Adam Trzciński
2017-08-22 10:31:04 +02:00
committed by Satyajit Sahoo
parent ca30661038
commit 572aa8ea1e
8 changed files with 109 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
/* @flow */
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { View, StyleSheet, Image } from 'react-native';
import { Colors, Button } from 'react-native-paper';
export default class ButtonExample extends Component {
@@ -12,6 +12,8 @@ export default class ButtonExample extends Component {
};
render() {
const uri = { uri: 'https://facebook.github.io/react/img/logo_og.png' };
const source = require('../assets/chameleon.jpg');
return (
<View style={styles.container}>
<View style={styles.row}>
@@ -49,6 +51,25 @@ export default class ButtonExample extends Component {
Loading
</Button>
</View>
<View style={styles.row}>
<Button raised icon={uri}>
Remote image
</Button>
<Button raised icon={source}>
Required asset
</Button>
<Button
icon={
<Image
source={source}
style={{ width: 16, height: 16, borderRadius: 10 }}
/>
}
raised
>
Custom component
</Button>
</View>
</View>
);
}

View File

@@ -17,6 +17,7 @@ import TouchableRipple from './TouchableRipple';
import { black, white } from '../styles/colors';
import withTheme from '../core/withTheme';
import type { Theme } from '../types/Theme';
import type { IconSource } from './Icon';
const AnimatedPaper = Animated.createAnimatedComponent(Paper);
@@ -27,7 +28,7 @@ type Props = {
primary?: boolean,
dark?: boolean,
loading?: boolean,
icon?: string,
icon?: IconSource,
color?: string,
children?: string | Array<string>,
onPress?: Function,
@@ -78,9 +79,17 @@ class Button extends PureComponent<void, Props, State> {
*/
loading: PropTypes.bool,
/**
* Icon name
* Icon name.
* Can be a string (name of MaterialIcon),
* an object {of shape {uri: 'https://path.to'}},
* required image from assets (const icon = reqiure('../path/to/image.png')),
* or any valid React-Native Component (e.g. <Image />)
*/
icon: PropTypes.string,
icon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({ uri: PropTypes.string }),
PropTypes.number,
]),
/**
* Custom text color for flat button, or background color for raised button
*/
@@ -144,9 +153,7 @@ class Button extends PureComponent<void, Props, State> {
} = this.props;
const { colors, roundness } = theme;
const fontFamily = theme.fonts.medium;
let backgroundColor, textColor, isDark;
if (raised) {
if (disabled) {
backgroundColor = 'rgba(0, 0, 0, .12)';

View File

@@ -9,9 +9,10 @@ import TouchableRipple from './TouchableRipple';
import { grey300 } from '../styles/colors';
import withTheme from '../core/withTheme';
import type { Theme } from '../types/Theme';
import type { IconSource } from './Icon';
type Props = {
icon?: string,
icon?: IconSource,
label: string,
active?: boolean,
onPress?: Function,

View File

@@ -10,11 +10,12 @@ import TouchableRipple from './TouchableRipple';
import { white } from '../styles/colors';
import withTheme from '../core/withTheme';
import type { Theme } from '../types/Theme';
import type { IconSource } from './Icon';
type Props = {
small?: boolean,
dark?: boolean,
icon: string,
icon: IconSource,
color?: string,
onPress?: Function,
theme: Theme,

View File

@@ -1,4 +1,67 @@
/* @flow */
import React from 'react';
import { Image, View } from 'react-native';
import PropTypes from 'prop-types';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
// eslint-disable-next-line import/named
export { default } from 'react-native-vector-icons/MaterialIcons';
export type IconSource = string | { uri: string } | number | React.Element<*>;
export type Props = {
name: IconSource,
size: number,
color?: string,
style?: any,
};
const Icon = ({ name, ...props }: Props) => {
if (typeof name === 'string') {
return <MaterialIcons {...props} name={name} />;
} else if (
(typeof name === 'object' &&
name.hasOwnProperty('uri') &&
typeof name.uri === 'string') ||
typeof name === 'number'
) {
return (
<Image
{...props}
source={name}
style={[
{
width: props.size,
height: props.size,
},
props.style,
]}
/>
);
}
return (
<View
{...props}
style={[
{
width: props.size,
height: props.size,
overflow: 'hidden',
},
props.style,
]}
>
{name}
</View>
);
};
export default Icon;
Icon.propTypes = {
name: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
size: PropTypes.number.isRequired,
color: PropTypes.string,
style: PropTypes.any,
};

View File

@@ -11,10 +11,11 @@ import TouchableIcon from './TouchableIcon';
import Paper from './Paper';
import { white } from '../styles/colors';
import type { Theme } from '../types/Theme';
import type { IconSource } from './Icon';
type Props = {
placeholder?: string,
icon?: string,
icon?: IconSource,
value: string,
onChangeText: (query: string) => void,
onIconPress?: Function,

View File

@@ -8,12 +8,13 @@ import color from 'color';
import { black, white } from '../../styles/colors';
import TouchableRipple from '../TouchableRipple';
import Icon from '../Icon';
import type { IconSource } from '../Icon';
const ANDROID_VERSION_LOLLIPOP = 21;
type Props = {
dark?: boolean,
icon: string,
icon: IconSource,
onPress?: Function,
style?: any,
};

View File

@@ -4,9 +4,10 @@ import React from 'react';
import TouchableRipple from './TouchableRipple';
import Icon from './Icon';
import type { IconSource } from './Icon';
type Props = {
name: string,
name: IconSource,
iconStyle?: any,
onPress: Function,
};