UNPKG

dis-gui

Version:

An extensible, styleable, & React-based controller library inspired by the venerable dat-gui.

107 lines (90 loc) 2.39 kB
'use strict'; import PropTypes from 'prop-types'; import React from 'react'; import sprintf from 'sprintf'; export default class Number extends React.PureComponent { constructor(props) { super(props); this.state = { invalid: false, value: this.props.value } } render() { return ( <input style={{ width: this.props.width, color: this.context.style.highlight, font: this.context.style.font, padding: `${this.context.style.paddingY}px ${this.context.style.paddingX}px`, backgroundColor: this.state.invalid ? this.context.style.lowlighterr : this.context.style.lowlight, border: 'none', outline: 'none', }} type='text' value={this.state.value} onChange={this.onChange.bind(this)} onKeyDown={this.onKeyDown.bind(this)} onBlur={this.onBlur.bind(this)} > </input> ) } componentWillReceiveProps(nextProps) { this.setState({ invalid: !this.isNumber(nextProps.value), value: this.truncate(nextProps.value), }); } truncate(value) { if (this.props.decimals !== undefined) { return sprintf(`%.${this.props.decimals}f`, parseFloat(value)); } return value; } onKeyDown(e) { if(e.which === 13) { this.handleChange(this.truncate(e.target.value)); } } onBlur(e) { this.handleChange(this.truncate(e.target.value)); } isNumber(value) { return !isNaN(value) && value !== ''; } onChange(e) { if (!this.isNumber(e.target.value)) { this.setState({ invalid: true, value: e.target.value }) return; } this.setState({ invalid: false, value: e.target.value }); } handleChange(value) { if (!this.state.invalid && this.props.onChange) { this.props.onChange(parseFloat(value)); } if (!this.state.invalid && this.props.onFinishChange) { this.props.onFinishChange(parseFloat(value)); } } } Number.propTypes = { value: PropTypes.number.isRequired, width: PropTypes.string, onChange: PropTypes.func, OnFinishChange: PropTypes.func, } Number.defaultProps = { width: '100%', } Number.contextTypes = { style: PropTypes.object, }