UNPKG

moq-ui

Version:

Simple, customizable UI components built with React

192 lines (165 loc) 4.53 kB
/** * @jsx React.DOM */ var React = require('react'); var Colors = require('./styles/colors'); var ColorManipulator = require('./utils/color-manipulator'); var StylePropable = require('./mixins/style-propable'); var ThemeManager = require('./styles/theme-manager'); var Transitions = require('./styles/transitions'); var Button = React.createClass({ mixins: [StylePropable], contextTypes: { uiTheme: React.PropTypes.object }, propTypes: { active: React.PropTypes.bool, disabled: React.PropTypes.bool, hidden: React.PropTypes.bool, invisible: React.PropTypes.bool, label: function(props, propName, componentName){ if (!props.children && !props.label) { return new Error('Required prop `label` or `children` was not specified in `'+ componentName + '`.') } }, linkButton: React.PropTypes.bool, primary: React.PropTypes.bool, labelStyle: React.PropTypes.object }, getDefaultProps: function() { return { type: "button" } }, getInitialState: function() { return { hovered: false, }; }, getTheme: function() { if (this.uiTheme === undefined) { this.uiTheme = this.context.uiTheme || new ThemeManager().getCurrentTheme() } return this.uiTheme; }, getThemeButton: function() { return this.getTheme().component.button; }, getStyles: function() { var styles = { core: { // structural display: 'inline-block', lineHeight: 'normal', whiteSpace: 'nowrap', verticalAlign: 'middle', textAlign: 'center', cursor: 'pointer', userDrag: 'none', userSelect: 'none', boxSizing: 'border-box', zoom: 1, // shared visual transition: Transitions.easeOut(), fontFamily: this.getTheme().fontFamily }, // the `look an feel` theme: this.getThemeButton(), // properties active: { boxShadow: '0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset' }, linkButton: { textDecoration: 'none' }, disabled: { cursor: (this.props.disabled) ? 'not-allowed' : 'pointer', opacity: 0.40, boxShadow: 'none' }, label: { position: 'relative', padding: '0 0', }, primary: { backgroundColor: this.getTheme().palette.primaryColor, color: 'white' } }; return styles; }, getClasses: function() { var classString = 'moq-button'; if (this.props.className && this.props.className.length) { classString += ' ' + this.props.className; } return classString; }, render: function() { var { className, active, hidden, invisible, label, linkButton, primary, onMouseOver, onMouseOut, ...other } = this.props; var styles = this.mergeAndPrefix( this.getStyles().core, this.getStyles().theme, this.props.active && this.getStyles().active, this.props.disabled && this.getStyles().disabled, this.props.linkButton && this.getStyles().linkButton, this.props.primary && this.getStyles().primary, this.props.style ); if (this.props.hidden) { styles.display = 'none'; } if (this.props.invisible) { styles.visibility = 'hidden'; } // Simulate the ':hover' effect if (this.state.hovered && !this.props.disabled) { styles.backgroundColor = ColorManipulator.darken(styles.backgroundColor, 0.05); } var labelElement; if (label) { labelElement = ( <span style={this.mergeAndPrefix(this.getStyles().label, this.props.labelStyle)}> {label} </span> ); } var buttonProps = { className: this.getClasses(), style: styles, onMouseOver: this._handleMouseOver, onMouseOut: this._handleMouseOut }; return linkButton ? ( <a {...other} {...buttonProps}> {labelElement} {this.props.children} </a> ) : ( <button {...other} {...buttonProps}> {labelElement} {this.props.children} </button> ); }, _handleMouseOver: function(e) { this.setState({hovered: true}); if (this.props.onMouseOver) this.props.onMouseOver(e); }, _handleMouseOut: function(e) { this.setState({hovered: false}); if (this.props.onMouseOut) this.props.onMouseOut(e); }, }); module.exports = Button;