cpr-mask
Version:
A masking component for react
252 lines (222 loc) • 11.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _lodash = require("lodash");
var _cprMaskHelpers = require("./cpr-mask.helpers.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var InputControl =
/*#__PURE__*/
function (_React$Component) {
_inherits(InputControl, _React$Component);
function InputControl(props) {
var _this;
_classCallCheck(this, InputControl);
_this = _possibleConstructorReturn(this, _getPrototypeOf(InputControl).call(this));
var encodedValue = props.encoder(props.initialValue);
var mask = (0, _lodash.find)(props.masks, function (mask) {
return mask.condition(encodedValue);
});
var maskValue;
if (!encodedValue) {
maskValue = "";
encodedValue = "";
} else if (props.validChars) {
if ((0, _cprMaskHelpers.testForValidChars)(encodedValue, props.validChars)) maskValue = props.initialValue;else {
maskValue = "";
encodedValue = "";
}
} else {
maskValue = props.initialValue && mask ? (0, _cprMaskHelpers.valueToMask)(encodedValue, mask.pattern, props.filler) : "";
}
_this.state = {
maskValue: maskValue,
value: encodedValue,
maskPattern: mask ? mask.pattern : null,
isDirty: false,
isFocused: false
};
return _this;
}
_createClass(InputControl, [{
key: "componentWillMount",
value: function componentWillMount() {
//Certain masks would not be compatible with each other. This function insures that they are.
if (!(0, _cprMaskHelpers.checkMasks)(this.props.masks)) throw Error("Incompatible masks");
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(props) {
//If the initial value is changing the component should update to be the new initial value
var encodedValue = props.encoder(props.initialValue);
if (props.validChars) {
if ((0, _cprMaskHelpers.testForValidChars)(encodedValue, props.validChars)) {
this.setState({
maskValue: encodedValue,
value: encodedValue || ""
});
}
} else {
var mask = (0, _lodash.find)(props.masks, function (mask) {
return mask.condition(encodedValue);
});
this.setState({
maskValue: props.initialValue && mask ? (0, _cprMaskHelpers.valueToMask)(encodedValue, mask.pattern, props.filler) : "",
value: encodedValue || "",
maskPattern: mask ? mask.pattern : null
});
}
}
}, {
key: "render",
value: function render() {
var _this2 = this;
var inputProps = this.props.inputProps || {};
var _this$state = this.state,
isDirty = _this$state.isDirty,
isFocused = _this$state.isFocused,
value = _this$state.value,
maskValue = _this$state.maskValue;
return _react.default.createElement("div", {
className: "\n ".concat(this.props.className, "\n ").concat((isDirty || !isFocused) && !this.props.validateMethod(value) ? this.props.invalidClass : "")
}, _react.default.createElement("div", {
style: {
display: "flex",
alignItems: "center"
}
}, this.props.sideChars.left ? _react.default.createElement("span", null, this.props.sideChars.left) : null, _react.default.createElement("input", _extends({
type: "text",
disabled: this.props.disabled,
ref: function ref(inputRef) {
return _this2.input = inputRef;
},
value: this.props.masks.length ? maskValue : value,
onChange: this.handleChange.bind(this),
onBlur: this.handleBlur.bind(this),
onMouseUp: this.selectionHandle.bind(this),
className: this.props.inputClass,
style: {
textAlign: this.props.alignment
},
onFocus: this.onFocus.bind(this),
placeholder: (0, _cprMaskHelpers.getPlaceholder)(this.props.placeholder, this.props.masks, this.props.validChars, this.props.filler)
}, inputProps)), this.props.sideChars.right ? _react.default.createElement("span", {
style: {
marginLeft: 5
}
}, this.props.sideChars.right) : null), (isDirty || !isFocused) && !this.props.validateMethod(value) ? _react.default.createElement("span", {
className: this.props.nonValidMsgClass
}, "".concat(this.props.nonValidMsg)) : null);
}
}, {
key: "selectionHandle",
value: function selectionHandle(e) {
if (this.state.maskPattern) {
var newCursor = (0, _cprMaskHelpers.getNewMaskCursor)(this.state.value, this.state.maskPattern);
if (this.input.selectionStart > newCursor) this.input.setSelectionRange(newCursor, newCursor);
}
}
}, {
key: "onFocus",
value: function onFocus(e) {
if (this.props.onFocus) this.props.onFocus(this.props.decoder ? this.props.decoder(this.state.value) : this.state.value);
this.setState({
isFocused: true
});
}
}, {
key: "handleBlur",
value: function handleBlur() {
//Show error messages on blur and run props.onBlur
if (this.props.onBlur) this.props.onBlur(this.props.decoder ? this.props.decoder(this.state.value) : this.state.value);
this.setState({
isDirty: true,
isFocused: false
});
}
}, {
key: "handleChange",
value: function handleChange(e) {
//if there is a validChars prop then it takes precedence over masks
//it only checks to see that the input characters match the validChars regex
if (this.props.validChars) _cprMaskHelpers.handleValidChars.call(this, e.target.value); //If there is no validChars and no mask you just have an input basically
else if (!this.props.masks.length) _cprMaskHelpers.handleNoMasks.call(this, e.target.value); //If there are masks there's some work to be done
else _cprMaskHelpers.handleMasks.call(this, e.target.value);
}
}]);
return InputControl;
}(_react.default.Component);
exports.default = InputControl;
_defineProperty(InputControl, "defaultProps", {
filler: " ",
initialValue: "",
alignment: "left",
invalidClass: "",
inputLabel: "",
className: "",
masks: [],
validateMethod: function validateMethod() {
return true;
},
sideChars: {},
encoder: function encoder(value) {
return value;
},
decoder: function decoder(value) {
return value;
}
});
_defineProperty(InputControl, "propTypes", {
//name given to the surrounding div
className: _propTypes.default.string,
//class given to the input field
inputClass: _propTypes.default.string,
//What value the component starts with
initialValue: _propTypes.default.string,
//class given to the error message
invalidClass: _propTypes.default.string,
//Decides which side of an input field the text appears on
alignment: _propTypes.default.oneOf(["left", "right"]),
//The message displayed when the input is invalid
nonValidMsg: _propTypes.default.string,
//The class applied to the nonValidMsg span
nonValidMsgClass: _propTypes.default.string,
//Characters to display on either side of the input
placeholder: _propTypes.default.string,
sideChars: _propTypes.default.shape({
left: _propTypes.default.string,
right: _propTypes.default.string
}),
//The variety of masks that could be displayed
//If there is no placeholder and no validChars the first mask's pattern will be used to make a placeholder
masks: _propTypes.default.arrayOf(_propTypes.default.shape({
condition: _propTypes.default.function,
pattern: _propTypes.default.string.isRequired
})),
//Regex that decides the validity of your input
validChars: _propTypes.default.object,
//is really a regex
//Function that decides if your input is valid and whether or not to show the invalid message and invalid classes
validateMethod: _propTypes.default.func,
//Function that can transform the value before passing it up
decoder: _propTypes.default.func,
//Function that changes value as it comes into cpr-mask
//Encoder should probably be used if you're using a decoder
encoder: _propTypes.default.func,
// Extra props to be placed on the <input /> (i.e., htmlFor, autocomplete, etc)
inputProps: _propTypes.default.object
});