1 | import React, { PureComponent } from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 | import createIconSet from './createIconSet';
|
4 | export default function createMultiStyleIconSet(styles, optionsInput = {}) {
|
5 | const styleNames = Object.keys(styles);
|
6 | if (styleNames.length === 0) {
|
7 | throw new Error('You need to add at least one style');
|
8 | }
|
9 | const options = {
|
10 | defaultStyle: styleNames[0],
|
11 | fallbackFamily: (_unused) => styleNames[0],
|
12 | glyphValidator: (_unused, __unused) => true,
|
13 | ...optionsInput,
|
14 | };
|
15 | const iconSets = styleNames.reduce((acc, name) => {
|
16 | const style = styles[name];
|
17 | acc[name] = createIconSet(style.glyphMap || {}, style.fontFamily || '', style.fontFile || '', style.fontStyle || {});
|
18 | return acc;
|
19 | }, {});
|
20 | function styleFromProps(props) {
|
21 | return Object.keys(props).reduce((result, propName) => styleNames.indexOf(propName) !== -1 && props[propName] === true
|
22 | ? propName
|
23 | : result, options.defaultStyle);
|
24 | }
|
25 | function getIconSetForProps(props) {
|
26 | const { name } = props;
|
27 | const style = styleFromProps(props);
|
28 | if (options.glyphValidator(name, style))
|
29 | return iconSets[style];
|
30 | const family = options.fallbackFamily(name);
|
31 | if (styleNames.indexOf(family) === -1) {
|
32 | return options.defaultStyle;
|
33 | }
|
34 | return iconSets[family];
|
35 | }
|
36 | function selectIconClass(iconSet, iconClass) {
|
37 | return iconClass.length > 0 ? iconSet[iconClass] : iconSet;
|
38 | }
|
39 | function reduceProps(props) {
|
40 | return Object.keys(props).reduce((acc, prop) => {
|
41 | if (styleNames.indexOf(prop) === -1) {
|
42 | acc[prop] = props[prop];
|
43 | }
|
44 | return acc;
|
45 | }, {});
|
46 | }
|
47 | function getStyledIconSet(style, name = '') {
|
48 | if (styleNames.indexOf(style) === -1) {
|
49 | return iconSets[options.defaultStyle];
|
50 | }
|
51 | return !name
|
52 | ? iconSets[styleFromProps({ [style]: true })]
|
53 | : getIconSetForProps({ name, [style]: true });
|
54 | }
|
55 | function getFontFamily(style = options.defaultStyle) {
|
56 | return getStyledIconSet(style).getFontFamily();
|
57 | }
|
58 | function getRawGlyphMap(style = options.defaultStyle) {
|
59 | return getStyledIconSet(style).getRawGlyphMap();
|
60 | }
|
61 | function hasIcon(name, style = options.defaultStyle) {
|
62 | return options.glyphValidator(name, style);
|
63 | }
|
64 | function createStyledIconClass(selectClass = '') {
|
65 | class IconClass extends PureComponent {
|
66 | render() {
|
67 | const selectedIconSet = getIconSetForProps(this.props);
|
68 | const SelectedIconClass = selectIconClass(selectedIconSet, selectClass);
|
69 | const props = reduceProps(this.props);
|
70 | return React.createElement(SelectedIconClass, props);
|
71 | }
|
72 | }
|
73 | IconClass.propTypes = styleNames.reduce((acc, name) => {
|
74 | acc[name] = PropTypes.bool;
|
75 | return acc;
|
76 | }, {});
|
77 | IconClass.defaultProps = styleNames.reduce((acc, name) => {
|
78 | acc[name] = false;
|
79 | return acc;
|
80 | }, {});
|
81 | IconClass.font = Object.values(styles).reduce((acc, style) => {
|
82 | acc[style.fontFamily] = style.fontFile;
|
83 | return acc;
|
84 | }, {});
|
85 | IconClass.StyledIconSet = getStyledIconSet;
|
86 | IconClass.getFontFamily = getFontFamily;
|
87 | IconClass.getRawGlyphMap = getRawGlyphMap;
|
88 | IconClass.hasIcon = hasIcon;
|
89 | return IconClass;
|
90 | }
|
91 | const Icon = createStyledIconClass();
|
92 | Icon.Button = createStyledIconClass('Button');
|
93 | return Icon;
|
94 | }
|
95 |
|
\ | No newline at end of file |