GT2/GT2-iOS/node_modules/react-native-vector-icons/lib/create-icon-set.js

177 lines
4.6 KiB
JavaScript

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
NativeModules,
Platform,
PixelRatio,
processColor,
Text,
} from './react-native';
import createIconButtonComponent from './icon-button';
import createTabBarItemIOSComponent from './tab-bar-item-ios';
import createToolbarAndroidComponent from './toolbar-android';
const NativeIconAPI =
NativeModules.RNVectorIconsManager || NativeModules.RNVectorIconsModule;
const DEFAULT_ICON_SIZE = 12;
const DEFAULT_ICON_COLOR = 'black';
export default function createIconSet(glyphMap, fontFamily, fontFile) {
let fontReference = fontFamily;
// Android doesn't care about actual fontFamily name, it will only look in fonts folder.
if (Platform.OS === 'android' && fontFile) {
fontReference = fontFile.replace(/\.(otf|ttf)$/, '');
}
if (Platform.OS === 'windows' && fontFile) {
fontReference = `Assets/${fontFile}#${fontFamily}`;
}
const IconNamePropType = PropTypes.oneOf(Object.keys(glyphMap));
class Icon extends Component {
static propTypes = {
name: IconNamePropType,
size: PropTypes.number,
color: PropTypes.string,
children: PropTypes.node,
style: PropTypes.any, // eslint-disable-line react/forbid-prop-types
};
static defaultProps = {
size: DEFAULT_ICON_SIZE,
allowFontScaling: false,
};
setNativeProps(nativeProps) {
if (this.root) {
this.root.setNativeProps(nativeProps);
}
}
root = null;
handleRef = ref => {
this.root = ref;
};
render() {
const { name, size, color, style, ...props } = this.props;
let glyph = name ? glyphMap[name] || '?' : '';
if (typeof glyph === 'number') {
glyph = String.fromCharCode(glyph);
}
const styleDefaults = {
fontSize: size,
color,
};
const styleOverrides = {
fontFamily: fontReference,
fontWeight: 'normal',
fontStyle: 'normal',
};
props.style = [styleDefaults, style, styleOverrides];
props.ref = this.handleRef;
return (
<Text {...props}>
{glyph}
{this.props.children}
</Text>
);
}
}
const imageSourceCache = {};
function ensureNativeModuleAvailable() {
if (!NativeIconAPI) {
if (Platform.OS === 'android') {
throw new Error(
'RNVectorIconsModule not available, did you properly integrate the module? Try running `react-native link react-native-vector-icons` and recompiling.'
);
}
throw new Error(
'RNVectorIconsManager not available, did you add the library to your project and link with libRNVectorIcons.a? Try running `react-native link react-native-vector-icons` and recompiling.'
);
}
}
function getImageSource(
name,
size = DEFAULT_ICON_SIZE,
color = DEFAULT_ICON_COLOR
) {
ensureNativeModuleAvailable();
let glyph = glyphMap[name] || '?';
if (typeof glyph === 'number') {
glyph = String.fromCharCode(glyph);
}
const processedColor = processColor(color);
const cacheKey = `${glyph}:${size}:${processedColor}`;
const scale = PixelRatio.get();
return new Promise((resolve, reject) => {
const cached = imageSourceCache[cacheKey];
if (typeof cached !== 'undefined') {
if (!cached || cached instanceof Error) {
reject(cached);
} else {
resolve({ uri: cached, scale });
}
} else {
NativeIconAPI.getImageForFont(
fontReference,
glyph,
size,
processedColor,
(err, image) => {
const error = typeof err === 'string' ? new Error(err) : err;
imageSourceCache[cacheKey] = image || error || false;
if (!error && image) {
resolve({ uri: image, scale });
} else {
reject(error);
}
}
);
}
});
}
function loadFont(file = fontFile) {
if (Platform.OS === 'ios') {
ensureNativeModuleAvailable();
if (!file) {
return Promise.reject(
new Error('Unable to load font, because no file was specified. ')
);
}
return NativeIconAPI.loadFontWithFileName(...file.split('.'));
}
return Promise.resolve();
}
Icon.Button = createIconButtonComponent(Icon);
Icon.TabBarItem = createTabBarItemIOSComponent(
IconNamePropType,
getImageSource
);
Icon.TabBarItemIOS = Icon.TabBarItem;
Icon.ToolbarAndroid = createToolbarAndroidComponent(
IconNamePropType,
getImageSource
);
Icon.getImageSource = getImageSource;
Icon.loadFont = loadFont;
return Icon;
}