d2-ui
Version:
151 lines (126 loc) • 3.51 kB
JSX
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;