UNPKG

3.25 kBJavaScriptView Raw
1import isString from 'lodash/isString';
2import omit from 'lodash/omit';
3import pick from 'lodash/pick';
4import React, { PureComponent } from 'react';
5import PropTypes from 'prop-types';
6import { StyleSheet, Text, TouchableHighlight, View } from './react-native';
7
8const styles = StyleSheet.create({
9 container: {
10 flexDirection: 'row',
11 justifyContent: 'flex-start',
12 alignItems: 'center',
13 padding: 8,
14 },
15 touchable: {
16 overflow: 'hidden',
17 },
18 icon: {
19 marginRight: 10,
20 },
21 text: {
22 fontWeight: '600',
23 backgroundColor: 'transparent',
24 },
25});
26
27const IOS7_BLUE = '#007AFF';
28
29const TEXT_PROP_NAMES = [
30 'ellipsizeMode',
31 'numberOfLines',
32 'textBreakStrategy',
33 'selectable',
34 'suppressHighlighting',
35 'allowFontScaling',
36 'adjustsFontSizeToFit',
37 'minimumFontScale',
38];
39
40const TOUCHABLE_PROP_NAMES = [
41 'accessible',
42 'accessibilityLabel',
43 'accessibilityHint',
44 'accessibilityComponentType',
45 'accessibilityRole',
46 'accessibilityStates',
47 'accessibilityTraits',
48 'onFocus',
49 'onBlur',
50 'disabled',
51 'onPress',
52 'onPressIn',
53 'onPressOut',
54 'onLayout',
55 'onLongPress',
56 'nativeID',
57 'testID',
58 'delayPressIn',
59 'delayPressOut',
60 'delayLongPress',
61 'activeOpacity',
62 'underlayColor',
63 'selectionColor',
64 'onShowUnderlay',
65 'onHideUnderlay',
66 'hasTVPreferredFocus',
67 'tvParallaxProperties',
68];
69
70export default function createIconButtonComponent(Icon) {
71 return class IconButton extends PureComponent {
72 static propTypes = {
73 backgroundColor: PropTypes.oneOfType([
74 PropTypes.string,
75 PropTypes.number,
76 ]),
77 borderRadius: PropTypes.number,
78 color: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
79 size: PropTypes.number,
80 iconStyle: PropTypes.any, // eslint-disable-line react/forbid-prop-types
81 style: PropTypes.any, // eslint-disable-line react/forbid-prop-types
82 children: PropTypes.node,
83 };
84
85 static defaultProps = {
86 backgroundColor: IOS7_BLUE,
87 borderRadius: 5,
88 color: 'white',
89 size: 20,
90 };
91
92 render() {
93 const { style, iconStyle, children, ...restProps } = this.props;
94
95 const iconProps = pick(
96 restProps,
97 TEXT_PROP_NAMES,
98 'style',
99 'name',
100 'size',
101 'color'
102 );
103 const touchableProps = pick(restProps, TOUCHABLE_PROP_NAMES);
104 const props = omit(
105 restProps,
106 Object.keys(iconProps),
107 Object.keys(touchableProps),
108 'iconStyle',
109 'borderRadius',
110 'backgroundColor'
111 );
112 iconProps.style = iconStyle ? [styles.icon, iconStyle] : styles.icon;
113
114 const colorStyle = pick(this.props, 'color');
115 const blockStyle = pick(this.props, 'backgroundColor', 'borderRadius');
116
117 return (
118 <TouchableHighlight
119 style={[styles.touchable, blockStyle]}
120 {...touchableProps}
121 >
122 <View style={[styles.container, blockStyle, style]} {...props}>
123 <Icon {...iconProps} />
124 {isString(children) ? (
125 <Text style={[styles.text, colorStyle]}>{children}</Text>
126 ) : (
127 children
128 )}
129 </View>
130 </TouchableHighlight>
131 );
132 }
133 };
134}