UNPKG

material-ui-number-input

Version:
305 lines (304 loc) 13.1 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var PropTypes = require("prop-types"); var TextField_1 = require("material-ui/TextField"); var ObjectAssign = require("object-assign"); var bind_decorator_1 = require("bind-decorator"); var errorNames; (function (errorNames) { errorNames.none = 'none'; errorNames.invalidSymbol = 'invalidSymbol'; errorNames.incompleteNumber = 'incompleteNumber'; errorNames.singleMinus = 'singleMinus'; errorNames.singleFloatingPoint = 'singleFloatingPoint'; errorNames.singleZero = 'singleZero'; errorNames.min = 'min'; errorNames.max = 'max'; errorNames.required = 'required'; errorNames.clean = 'clean'; errorNames.allow = 'allow'; errorNames.limit = 'limit'; })(errorNames || (errorNames = {})); var strategies; (function (strategies) { strategies.ignore = 'ignore'; strategies.warn = 'warn'; strategies.allow = 'allow'; })(strategies || (strategies = {})); var typeofs; (function (typeofs) { typeofs.stringType = 'string'; typeofs.numberType = 'number'; })(typeofs || (typeofs = {})); var constants; (function (constants) { constants.emptyString = ''; constants.dash = '-'; constants.dot = '.'; constants.zero = 0; constants.one = 1; constants.text = 'text'; constants.zeroString = '0'; constants.minusOne = -1; constants.boolTrue = true; constants.boolFalse = false; })(constants || (constants = {})); var NumberInput = (function (_super) { __extends(NumberInput, _super); function NumberInput(props) { var _this = _super.call(this, props) || this; _this.constProps = { type: constants.text, onChange: _this.onChange, onBlur: _this.onBlur, ref: _this.refTextField }; return _this; } NumberInput.getValidValue = function (value) { var match = value.match(NumberInput.allowed); return match !== null ? (match.index === constants.zero ? match[constants.zero] : match.join(constants.emptyString)) : constants.emptyString; }; NumberInput.deleteOwnProps = function (props) { var prop; for (var index = 0; index < NumberInput.deleteProps.length; ++index) { prop = NumberInput.deleteProps[index]; if (props.hasOwnProperty(prop)) { delete props[prop]; } } }; NumberInput.validateNumberValue = function (value, props) { var max = props.max, min = props.min; if ((typeof max === typeofs.numberType) && (value > max)) { return constants.one; } if ((typeof min === typeofs.numberType) && (value < min)) { return constants.minusOne; } return constants.zero; }; NumberInput.validateValue = function (value, props) { var required = props.required, strategy = props.strategy, min = props.min; if (value === constants.emptyString) { return required ? errorNames.required : errorNames.clean; } else { if (value.match(NumberInput.validSymbols)) { if (value.match(NumberInput.stricAllowed)) { if (value.match(NumberInput.validNumber)) { var numberValue = Number(value); var floatingPoint = value.indexOf(constants.dot); var decimal = floatingPoint > constants.minusOne; var whole = decimal ? Number(value.substring(constants.zero, floatingPoint)) : min; switch (NumberInput.validateNumberValue(numberValue, props)) { case constants.one: return errorNames.max; case constants.minusOne: return ((strategy !== strategies.allow) && (min > constants.zero) && (numberValue > constants.zero) && (!decimal || (decimal && (whole > min)))) ? errorNames.allow : errorNames.min; default: return errorNames.none; } } else { return (strategy !== strategies.allow) && (value === constants.dash) && (min >= constants.zero) ? errorNames.limit : (min < 0 ? errorNames.allow : errorNames.incompleteNumber); } } else { switch (value[value.length - constants.one]) { case constants.dash: return errorNames.singleMinus; case constants.dot: return errorNames.singleFloatingPoint; case constants.zeroString: return errorNames.singleZero; default: return errorNames.invalidSymbol; } } } else { return errorNames.invalidSymbol; } } }; NumberInput.overrideRequestedValue = function (error, value, props) { switch (error) { case errorNames.min: return String(props.min); case errorNames.max: return String(props.max); default: return props.strategy !== strategies.allow && value === constants.dash && props.min >= 0 ? constants.emptyString : value; } }; NumberInput.overrideError = function (error, props) { switch (error) { case errorNames.allow: return errorNames.none; case errorNames.limit: return props.required ? errorNames.required : errorNames.clean; default: return error; } }; NumberInput.revertAllowToMin = function (error) { return error === errorNames.allow ? errorNames.min : error; }; NumberInput.emitValid = function (error, overridenError) { return (error !== errorNames.allow) && (overridenError === errorNames.none); }; NumberInput.prototype.emitEvents = function (nextError, value, valid, props) { var onError = props.onError, onValid = props.onValid; if ((this.error !== nextError) && (props.strategy !== strategies.ignore)) { if (onError) { onError(nextError); } this.error = nextError; } if (onValid && valid && (this.lastValid !== value)) { onValid(Number(value)); this.lastValid = value; } }; NumberInput.prototype.takeActionForValue = function (value, props) { var strategy = props.strategy, onRequestValue = props.onRequestValue, propsValue = props.value; var error = NumberInput.validateValue(value, props); var valid = NumberInput.overrideRequestedValue(error, NumberInput.getValidValue(value), props); var overridenError = NumberInput.overrideError(error, props); var emitValid = NumberInput.emitValid(error, overridenError); this.emitEvents(overridenError, valid, emitValid, props); if ((strategy !== strategies.allow) && (valid !== value)) { if (typeof propsValue !== typeofs.stringType) { this.getInputNode().value = valid; } else if (onRequestValue) { onRequestValue(valid); } } }; NumberInput.prototype.shouldTakeActionForValue = function (props) { var _a = this.props, min = _a.min, max = _a.max, required = _a.required, strategy = _a.strategy; return (min !== props.min) || (max !== props.max) || (required !== props.required) || (strategy !== props.strategy); }; NumberInput.prototype.refTextField = function (textField) { this.textField = textField; }; NumberInput.prototype.onChange = function (event) { var value = event.currentTarget.value; var onChange = this.props.onChange; if (onChange) { onChange(event, value); } if (typeof this.props.value !== typeofs.stringType) { this.takeActionForValue(value, this.props); } }; NumberInput.prototype.onBlur = function (event) { var value = event.currentTarget.value; var props = this.props; var onBlur = props.onBlur; var error = NumberInput.overrideError(NumberInput.revertAllowToMin(NumberInput.validateValue(value, props)), props); this.emitEvents(error, value, constants.boolFalse, props); if (onBlur) { onBlur(event); } }; NumberInput.prototype.getInputNode = function () { return this.textField.getInputNode(); }; NumberInput.prototype.getTextField = function () { return this.textField; }; NumberInput.prototype.componentDidMount = function () { var props = this.props; var value = props.value; this.takeActionForValue(typeof value === typeofs.stringType ? value : this.getInputNode().value, props); }; NumberInput.prototype.componentWillReceiveProps = function (props) { var value = props.value; if ((value !== this.props.value) || this.shouldTakeActionForValue(props)) { this.takeActionForValue(value, props); } }; NumberInput.prototype.render = function () { var _a = this, props = _a.props, constProps = _a.constProps; var value = props.value, defaultValue = props.defaultValue; var inputProps = ObjectAssign({}, props, constProps, { defaultValue: typeof defaultValue === typeofs.numberType ? String(defaultValue) : undefined, value: value, }); if (typeof inputProps.value !== typeofs.stringType) { delete inputProps.value; } if (inputProps.defaultValue === undefined) { delete inputProps.defaultValue; } NumberInput.deleteOwnProps(inputProps); return React.createElement(TextField_1.default, inputProps); }; NumberInput.validSymbols = /(\-|\.|\d)+/; NumberInput.stricAllowed = /^-?((0|([1-9]\d{0,}))(\.\d{0,})?)?$/; NumberInput.validNumber = /^-?((0(\.\d+)?)|([1-9]\d{0,}(\.\d+)?))$/; NumberInput.allowed = /-?((0|([1-9]\d{0,}))(\.\d{0,})?)?/; NumberInput.deleteProps = ['strategy', 'onError', 'onValid', 'onRequestValue']; NumberInput.propTypes = { className: PropTypes.string, disabled: PropTypes.bool, errorStyle: PropTypes.object, errorText: PropTypes.node, floatingLabelFixed: PropTypes.bool, floatingLabelFocusStyle: PropTypes.object, floatingLabelStyle: PropTypes.object, floatingLabelText: PropTypes.node, fullWidth: PropTypes.bool, hintStyle: PropTypes.object, hintText: PropTypes.node, id: PropTypes.string, inputStyle: PropTypes.object, name: PropTypes.string, onBlur: PropTypes.func, onChange: PropTypes.func, onFocus: PropTypes.func, onValid: PropTypes.func, onError: PropTypes.func, onRequestValue: PropTypes.func, onKeyDown: PropTypes.func, style: PropTypes.object, underlineDisabledStyle: PropTypes.object, underlineFocusStyle: PropTypes.object, underlineShow: PropTypes.bool, underlineStyle: PropTypes.object, defaultValue: PropTypes.number, min: PropTypes.number, max: PropTypes.number, required: PropTypes.bool, strategy: PropTypes.oneOf([ strategies.ignore, strategies.warn, strategies.allow ]), value: PropTypes.string }; NumberInput.defaultProps = { required: constants.boolFalse, strategy: strategies.allow }; __decorate([ bind_decorator_1.default ], NumberInput.prototype, "refTextField", null); __decorate([ bind_decorator_1.default ], NumberInput.prototype, "onChange", null); __decorate([ bind_decorator_1.default ], NumberInput.prototype, "onBlur", null); return NumberInput; }(React.Component)); exports.NumberInput = NumberInput; exports.default = NumberInput;