BREAKING: Remove support for React elements for icon prop

Use render callback instead
This commit is contained in:
Satyajit Sahoo
2018-05-10 14:32:25 +02:00
parent 8c5bc5165b
commit 65ad2a0457
15 changed files with 38 additions and 58 deletions

View File

@@ -732,7 +732,7 @@ class BottomNavigation<T: *> extends React.Component<Props<T>, State> {
})
) : (
<Icon
name={(route: Object).icon}
source={(route: Object).icon}
color={activeColor}
size={24}
/>
@@ -753,7 +753,7 @@ class BottomNavigation<T: *> extends React.Component<Props<T>, State> {
})
) : (
<Icon
name={(route: Object).icon}
source={(route: Object).icon}
color={inactiveColor}
size={24}
/>

View File

@@ -207,7 +207,7 @@ class Button extends React.Component<Props, State> {
<View style={styles.content}>
{icon && loading !== true ? (
<View style={styles.icon}>
<Icon name={icon} size={16} color={textColor} />
<Icon source={icon} size={16} color={textColor} />
</View>
) : null}
{loading ? (

View File

@@ -67,7 +67,7 @@ class Checkbox extends React.Component<Props> {
<View style={{ opacity: checked ? 1 : 0 }}>
<Icon
allowFontScaling={false}
name="done"
source="done"
size={24}
color={checkedColor}
/>

View File

@@ -147,7 +147,7 @@ class Checkbox extends React.Component<Props, State> {
<Animated.View style={{ transform: [{ scale: this.state.scaleAnim }] }}>
<Icon
allowFontScaling={false}
name={checked ? 'check-box' : 'check-box-outline-blank'}
source={checked ? 'check-box' : 'check-box-outline-blank'}
size={24}
color={checkboxColor}
/>

View File

@@ -75,7 +75,7 @@ class Chip extends React.Component<Props> {
return (
<TouchableWithoutFeedback onPress={onPress}>
<View style={[styles.content, { backgroundColor }, style]}>
{icon ? <Icon name={icon} color={iconColor} size={32} /> : null}
{icon ? <Icon source={icon} color={iconColor} size={32} /> : null}
<Text
numberOfLines={1}
style={[
@@ -92,7 +92,7 @@ class Chip extends React.Component<Props> {
{onDelete ? (
<TouchableWithoutFeedback onPress={onDelete}>
<View style={styles.delete}>
<Icon name="cancel" size={20} color={iconColor} />
<Icon source="cancel" size={20} color={iconColor} />
</View>
</TouchableWithoutFeedback>
) : null}

View File

@@ -105,7 +105,7 @@ class CrossFadeIcon extends React.Component<Props, State> {
},
]}
>
<Icon name={this.state.previousIcon} size={size} color={color} />
<Icon source={this.state.previousIcon} size={size} color={color} />
</Animated.View>
) : null}
<Animated.View
@@ -117,7 +117,7 @@ class CrossFadeIcon extends React.Component<Props, State> {
},
]}
>
<Icon name={this.state.currentIcon} size={size} color={color} />
<Icon source={this.state.currentIcon} size={size} color={color} />
</Animated.View>
</View>
);

View File

@@ -81,7 +81,7 @@ class DrawerItem extends React.Component<Props> {
return (
<TouchableRipple {...props}>
<View style={[styles.wrapper, { backgroundColor }]}>
{icon && <Icon name={icon} size={24} color={iconColor} />}
{icon && <Icon source={icon} size={24} color={iconColor} />}
<Text
numberOfLines={1}
style={[

View File

@@ -1,7 +1,7 @@
/* @flow */
import * as React from 'react';
import { Image, Text, View, StyleSheet } from 'react-native';
import { Image, Text, StyleSheet } from 'react-native';
let MaterialIcons;
@@ -31,9 +31,7 @@ export type IconSource =
| string
| number
| { uri: string }
| ((props: IconProps) => React.Node)
// This will be removed in next major version
| React.Node;
| ((props: IconProps) => React.Node);
type IconProps = {
color: string,
@@ -41,7 +39,7 @@ type IconProps = {
};
type Props = IconProps & {
name: IconSource,
source: IconSource,
};
const isImageSource = (source: any) =>
@@ -72,23 +70,23 @@ export const isValidIcon = (source: any) =>
export const isEqualIcon = (a: any, b: any) =>
a === b || getIconId(a) === getIconId(b);
const Icon = ({ name, color, size, ...rest }: Props) => {
if (typeof name === 'string') {
const Icon = ({ source, color, size, ...rest }: Props) => {
if (typeof source === 'string') {
return (
<MaterialIcons
{...rest}
name={name}
name={source}
color={color}
size={size}
style={styles.icon}
pointerEvents="none"
/>
);
} else if (isImageSource(name)) {
} else if (isImageSource(source)) {
return (
<Image
{...rest}
source={name}
source={source}
style={[
{
width: size,
@@ -98,35 +96,16 @@ const Icon = ({ name, color, size, ...rest }: Props) => {
]}
/>
);
} else if (typeof name === 'function') {
return name({ color, size });
} else if (typeof source === 'function') {
return source({ color, size });
}
return (
<View
{...rest}
style={[
{
width: size,
height: size,
},
styles.container,
]}
pointerEvents="box-none"
>
{(name: any)}
</View>
);
return null;
};
export default Icon;
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
},
icon: {
backgroundColor: 'transparent',
},

View File

@@ -4,7 +4,7 @@ import color from 'color';
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import TouchableRipple from '../TouchableRipple';
import Icon from '../Icon';
import Icon, { type IconSource } from '../Icon';
import Text from '../Typography/Text';
import withTheme from '../../core/withTheme';
import type { Theme } from '../../types';
@@ -21,7 +21,7 @@ type Props = {
/**
* Icon to display for the `ListAccordion`.
*/
icon?: React.Node,
icon?: IconSource,
/**
* Content of the section.
@@ -101,7 +101,7 @@ class ListAccordion extends React.Component<Props, State> {
]}
>
<Icon
name={icon}
source={icon}
size={24}
color={
this.state.expanded
@@ -141,7 +141,7 @@ class ListAccordion extends React.Component<Props, State> {
</View>
<View style={[styles.item, description && styles.multiline]}>
<Icon
name={
source={
this.state.expanded
? 'keyboard-arrow-up'
: 'keyboard-arrow-down'

View File

@@ -88,9 +88,10 @@ class ListItem extends React.Component<Props> {
description && styles.multiline,
]}
>
{avatar || (
<Icon name={icon} size={24} color={descriptionColor} />
)}
{avatar ||
(icon ? (
<Icon source={icon} size={24} color={descriptionColor} />
) : null)}
</View>
) : null}
<View style={[styles.item, styles.content]}>
@@ -116,7 +117,7 @@ class ListItem extends React.Component<Props> {
</View>
{avatar && icon ? (
<View style={[styles.item, description && styles.multiline]}>
<Icon name={icon} size={24} color={descriptionColor} />
<Icon source={icon} size={24} color={descriptionColor} />
</View>
) : null}
</View>

View File

@@ -85,7 +85,7 @@ class RadioButton extends React.Component<Props> {
<View style={{ opacity: checked ? 1 : 0 }}>
<Icon
allowFontScaling={false}
name={checked && 'done'}
source="done"
size={24}
color={checkedColor}
/>

View File

@@ -147,7 +147,7 @@ class Searchbar extends React.Component<Props> {
rippleColor={rippleColor}
onPress={onIconPress}
color={iconColor}
name={icon || 'search'}
source={icon || 'search'}
/>
<TextInput
style={[styles.input, { color: textColor }]}
@@ -168,7 +168,7 @@ class Searchbar extends React.Component<Props> {
color={iconColor}
rippleColor={rippleColor}
onPress={this._handleClearPress}
name="close"
source="close"
/>
) : null}
</Paper>

View File

@@ -59,7 +59,7 @@ export default class ToolbarAction extends React.Component<Props> {
<TouchableIcon
onPress={onPress}
color={iconColor}
name={icon}
source={icon}
{...rest}
/>
);

View File

@@ -29,7 +29,7 @@ const ToolbarBackAction = (props: Props) => {
const icon =
Platform.OS === 'ios'
? ({ color }) => (
<Icon name="keyboard-arrow-left" size={36} color={color} />
<Icon source="keyboard-arrow-left" size={36} color={color} />
)
: 'arrow-back';

View File

@@ -9,7 +9,7 @@ import Icon from './Icon';
import type { IconSource } from './Icon';
type Props = {
name: IconSource,
source: IconSource,
color: string,
size?: number,
onPress: ?Function,
@@ -17,7 +17,7 @@ type Props = {
};
const TouchableIcon = ({
name,
source,
color: iconColor,
size = 24,
onPress,
@@ -43,7 +43,7 @@ const TouchableIcon = ({
{...rest}
>
<View>
<Icon color={iconColor} name={name} size={size} />
<Icon color={iconColor} source={source} size={size} />
</View>
</TouchableRipple>
);