nuke-icon
Version:
图标
138 lines (124 loc) • 3.51 kB
JSX
/** @jsx createElement */
;
import { Component, createElement, PropTypes } from 'rax';
import Text from 'nuke-text';
import { isWeb } from 'nuke-env';
import Touchable from 'nuke-touchable';
import Image from 'nuke-image';
import Iconfont, { formatUnicode } from 'nuke-iconfont';
import { connectStyle } from 'nuke-theme-provider';
import stylesProvider from '../styles';
class Icon extends Component {
constructor(props) {
super(props);
const { themeStyle } = props;
this.fontURL =
themeStyle['icon-font-path'].raw || themeStyle['icon-font-path'];
this.fontName =
themeStyle['icon-font-family'].raw || themeStyle['icon-font-family'];
}
componentDidMount() {
const type = this.getType();
if (type === 'iconfont') {
let tmpFontURL = this.fontURL;
if (this.fontURL.indexOf('.ttf') <= -1) {
tmpFontURL += '.ttf';
}
Iconfont({ name: this.fontName, url: tmpFontURL });
}
}
componentWillReceiveProps(nextProps) {
const type = this.getType();
if (type === 'iconfont') {
const { themeStyle } = nextProps;
const curFontUrl =
themeStyle['icon-font-path'].raw || themeStyle['icon-font-path'];
const curFontName =
themeStyle['icon-font-family'].raw || themeStyle['icon-font-family'];
if (curFontUrl !== this.fontURL || curFontName !== this.fontName) {
this.fontURL = curFontUrl;
this.fontName = curFontName;
let tmpFontURL = this.fontURL;
if (this.fontURL.indexOf('.ttf') <= -1) {
tmpFontURL += '.ttf';
}
Iconfont({ name: this.fontName, url: tmpFontURL });
}
}
}
getType() {
const { name = '' } = this.props;
let { type = 'image' } = this.props;
if (type === 'image' && name !== '') {
type = 'iconfont';
}
return type;
}
render() {
const {
size,
name = '',
style,
onPress,
fixedFont,
...others
} = this.props;
const styles = this.props.themeStyle;
const type = this.getType();
if (type === 'iconfont') {
const textStyle = Object.assign({}, styles[`iconfont-${size}`], style, {
fontFamily: this.fontName,
});
const unicode =
styles[`icon-content-${name}`] &&
formatUnicode(styles[`icon-content-${name}`], 16);
return (
<Text
onClick={onPress}
{...others}
fixedFont={fixedFont}
style={textStyle}
>
{unicode}
</Text>
);
}
const wrapStyle = Object.assign({}, styles['icon-image'], style);
const sizeStyle = styles[`image-${size}`];
return (
<Touchable onPress={onPress} style={wrapStyle} {...others}>
<Image
source={{ uri: this.props.src }}
style={sizeStyle}
resizeMode={'cover'}
/>
</Touchable>
);
}
}
Icon.displayName = 'Icon';
Icon.defaultProps = {
size: 'medium',
style: {},
name: '',
onPress: () => {},
src: '',
type: 'image',
fixedFont: false,
};
Icon.propTypes = {
onPress: PropTypes.func,
name: PropTypes.any,
themeStyle: PropTypes.any,
style: PropTypes.any,
src: PropTypes.string,
type: PropTypes.string,
size: PropTypes.oneOf(['xs', 'small', 'medium', 'large']),
fixedFont: PropTypes.boolean,
};
Icon.contextTypes = {
parentPath: PropTypes.any,
parentStyle: PropTypes.any,
};
const StyledIcon = connectStyle(stylesProvider)(Icon);
export default StyledIcon;