UNPKG

3.64 kBJavaScriptView Raw
1import React, { PureComponent } from 'react';
2import PropTypes from 'prop-types';
3
4import createIconSet, {
5 DEFAULT_ICON_COLOR,
6 DEFAULT_ICON_SIZE,
7} from './create-icon-set';
8
9export default function createMultiStyleIconSet(styles, optionsInput = {}) {
10 const styleNames = Object.keys(styles);
11
12 if (styleNames.length === 0) {
13 throw new Error('You need to add at least one style');
14 }
15
16 const options = {
17 defaultStyle: styleNames[0],
18 fallbackFamily: () => styleNames[0],
19 glyphValidator: () => true,
20 ...optionsInput,
21 };
22
23 const iconSets = styleNames.reduce((acc, name) => {
24 const style = styles[name];
25
26 acc[name] = createIconSet(
27 style.glyphMap || {},
28 style.fontFamily || '',
29 style.fontFile || '',
30 style.fontStyle || {}
31 );
32
33 return acc;
34 }, {});
35
36 function styleFromProps(props) {
37 return Object.keys(props).reduce(
38 (result, propName) =>
39 styleNames.indexOf(propName) !== -1 && props[propName] === true
40 ? propName
41 : result,
42 options.defaultStyle
43 );
44 }
45
46 function getIconSetForProps(props) {
47 const { name } = props;
48 const style = styleFromProps(props);
49
50 if (options.glyphValidator(name, style)) return iconSets[style];
51
52 const family = options.fallbackFamily(name);
53
54 if (styleNames.indexOf(family) === -1) {
55 return options.defaultStyle;
56 }
57
58 return iconSets[family];
59 }
60
61 function selectIconClass(iconSet, iconClass) {
62 return iconClass.length > 0 ? iconSet[iconClass] : iconSet;
63 }
64
65 function reduceProps(props) {
66 return Object.keys(props).reduce((acc, prop) => {
67 if (styleNames.indexOf(prop) === -1) {
68 acc[prop] = props[prop];
69 }
70
71 return acc;
72 }, {});
73 }
74
75 function getStyledIconSet(style, name = '') {
76 if (styleNames.indexOf(style) === -1) {
77 return iconSets[options.defaultStyle];
78 }
79
80 return !name
81 ? iconSets[styleFromProps({ [style]: true })]
82 : getIconSetForProps({ name, [style]: true });
83 }
84
85 function getImageSource(
86 name,
87 size = DEFAULT_ICON_SIZE,
88 color = DEFAULT_ICON_COLOR,
89 style = options.defaultStyle
90 ) {
91 return getStyledIconSet(style, name).getImageSource(name, size, color);
92 }
93
94 function getFontFamily(style = options.defaultStyle) {
95 return getStyledIconSet(style).getFontFamily();
96 }
97
98 function getRawGlyphMap(style = options.defaultStyle) {
99 return getStyledIconSet(style).getRawGlyphMap();
100 }
101
102 function hasIcon(name, style = options.defaultStyle) {
103 return options.glyphValidator(name, style);
104 }
105
106 function createStyledIconClass(selectClass = '') {
107 class IconClass extends PureComponent {
108 static propTypes = styleNames.reduce((acc, name) => {
109 acc[name] = PropTypes.bool;
110 return acc;
111 }, {});
112
113 static defaultProps = styleNames.reduce((acc, name) => {
114 acc[name] = false;
115 return acc;
116 }, {});
117
118 render() {
119 const selectedIconSet = getIconSetForProps(this.props);
120 const SelectedIconClass = selectIconClass(selectedIconSet, selectClass);
121 const props = reduceProps(this.props);
122
123 return <SelectedIconClass {...props} />;
124 }
125 }
126
127 return IconClass;
128 }
129
130 const Icon = createStyledIconClass();
131 Icon.Button = createStyledIconClass('Button');
132 Icon.TabBarItem = createStyledIconClass('TabBarItem');
133 Icon.TabBarItemIOS = createStyledIconClass('TabBarItemIOS');
134 Icon.getStyledIconSet = getStyledIconSet;
135 Icon.getImageSource = getImageSource;
136 Icon.getFontFamily = getFontFamily;
137 Icon.getRawGlyphMap = getRawGlyphMap;
138 Icon.hasIcon = hasIcon;
139
140 return Icon;
141}
142
\No newline at end of file