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