UNPKG

nuke-icon

Version:

图标

138 lines (124 loc) 3.51 kB
/** @jsx createElement */ 'use strict'; 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;