UNPKG

d2-ui

Version:
151 lines (126 loc) 3.51 kB
import React from 'react'; import StylePropable from './mixins/style-propable'; import Transitions from './styles/transitions'; import getMuiTheme from './styles/getMuiTheme'; const SvgIcon = React.createClass({ propTypes: { /** * Elements passed into the SVG Icon. */ children: React.PropTypes.node, /** * This is the fill color of the svg icon. * If not specified, this component will default * to muiTheme.palette.textColor. */ color: React.PropTypes.string, /** * This is the icon color when the mouse hovers over the icon. */ hoverColor: React.PropTypes.string, /** * Function called when mouse enters this element. */ onMouseEnter: React.PropTypes.func, /** * Function called when mouse leaves this element. */ onMouseLeave: React.PropTypes.func, /** * Override the inline-styles of the root element. */ style: React.PropTypes.object, /** * Allows you to redifine what the coordinates * without units mean inside an svg element. For example, * if the SVG element is 500 (width) by 200 (height), and you * pass viewBox="0 0 50 20", this means that the coordinates inside * the svg will go from the top left corner (0,0) to bottom right (50,20) * and each unit will be worth 10px. */ viewBox: React.PropTypes.string, }, contextTypes: { muiTheme: React.PropTypes.object, }, //for passing default theme context to children childContextTypes: { muiTheme: React.PropTypes.object, }, mixins: [ StylePropable, ], getDefaultProps() { return { onMouseEnter: () => {}, onMouseLeave: () => {}, viewBox: '0 0 24 24', }; }, getInitialState() { return { hovered: false, muiTheme: this.context.muiTheme || getMuiTheme(), }; }, getChildContext() { return { muiTheme: this.state.muiTheme, }; }, //to update theme inside state whenever a new theme is passed down //from the parent / owner using context componentWillReceiveProps(nextProps, nextContext) { let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme; this.setState({muiTheme: newMuiTheme}); }, _handleMouseLeave(e) { this.setState({hovered: false}); this.props.onMouseLeave(e); }, _handleMouseEnter(e) { this.setState({hovered: true}); this.props.onMouseEnter(e); }, render() { const { children, color, hoverColor, onMouseEnter, onMouseLeave, style, viewBox, ...other, } = this.props; const offColor = color ? color : style && style.fill ? style.fill : this.state.muiTheme.rawTheme.palette.textColor; const onColor = hoverColor ? hoverColor : offColor; const mergedStyles = this.mergeStyles({ display: 'inline-block', height: 24, width: 24, userSelect: 'none', transition: Transitions.easeOut(), }, style, { // Make sure our fill color overrides fill provided in props.style fill: this.state.hovered ? onColor : offColor, }); const events = hoverColor ? { onMouseEnter: this._handleMouseEnter, onMouseLeave: this._handleMouseLeave, } : {}; return ( <svg {...other} {...events} style={this.prepareStyles(mergedStyles)} viewBox={viewBox} > {children} </svg> ); }, }); export default SvgIcon;