UNPKG

@skbkontur/react-imask

Version:

React input mask

210 lines 8.26 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IMaskMixin; const react_1 = __importDefault(require("react")); const prop_types_1 = __importDefault(require("prop-types")); const imask_1 = __importDefault(require("@skbkontur/imask")); const MASK_PROPS = { // common mask: prop_types_1.default.oneOfType([ prop_types_1.default.array, prop_types_1.default.func, prop_types_1.default.string, prop_types_1.default.instanceOf(RegExp), prop_types_1.default.oneOf([Date, Number, imask_1.default.Masked]), prop_types_1.default.instanceOf(imask_1.default.Masked), ]), value: prop_types_1.default.any, unmask: prop_types_1.default.oneOfType([ prop_types_1.default.bool, prop_types_1.default.oneOf(['typed']), ]), prepare: prop_types_1.default.func, prepareChar: prop_types_1.default.func, validate: prop_types_1.default.func, commit: prop_types_1.default.func, overwrite: prop_types_1.default.oneOfType([ prop_types_1.default.bool, prop_types_1.default.oneOf(['shift']), ]), eager: prop_types_1.default.oneOfType([ prop_types_1.default.bool, prop_types_1.default.oneOf(['append', 'remove']), ]), skipInvalid: prop_types_1.default.bool, // events onAccept: prop_types_1.default.func, onComplete: prop_types_1.default.func, // pattern placeholderChar: prop_types_1.default.string, displayChar: prop_types_1.default.string, lazy: prop_types_1.default.bool, definitions: prop_types_1.default.object, blocks: prop_types_1.default.object, // enum enum: prop_types_1.default.arrayOf(prop_types_1.default.string), // range maxLength: prop_types_1.default.number, from: prop_types_1.default.number, to: prop_types_1.default.number, // date pattern: prop_types_1.default.string, format: prop_types_1.default.func, parse: prop_types_1.default.func, autofix: prop_types_1.default.oneOfType([ prop_types_1.default.bool, prop_types_1.default.oneOf(['pad']), ]), // number radix: prop_types_1.default.string, thousandsSeparator: prop_types_1.default.string, mapToRadix: prop_types_1.default.arrayOf(prop_types_1.default.string), scale: prop_types_1.default.number, normalizeZeros: prop_types_1.default.bool, padFractionalZeros: prop_types_1.default.bool, min: prop_types_1.default.oneOfType([ prop_types_1.default.number, prop_types_1.default.instanceOf(Date), ]), max: prop_types_1.default.oneOfType([ prop_types_1.default.number, prop_types_1.default.instanceOf(Date), ]), // dynamic dispatch: prop_types_1.default.func, // ref inputRef: prop_types_1.default.oneOfType([ prop_types_1.default.func, prop_types_1.default.shape({ current: prop_types_1.default.object }), ]), }; const MASK_PROPS_NAMES = Object.keys(MASK_PROPS).filter(p => p !== 'value'); const NON_MASK_OPTIONS_NAMES = ['value', 'unmask', 'onAccept', 'onComplete', 'inputRef']; const MASK_OPTIONS_NAMES = MASK_PROPS_NAMES.filter(pName => NON_MASK_OPTIONS_NAMES.indexOf(pName) < 0); function IMaskMixin(ComposedComponent) { const MaskedComponent = class extends react_1.default.Component { constructor(props) { super(props); this._inputRef = this._inputRef.bind(this); } componentDidMount() { if (!this.props.mask) return; this.initMask(); } componentDidUpdate() { var _a; const props = this.props; const maskOptions = this._extractMaskOptionsFromProps(props); if (maskOptions.mask) { if (this.maskRef) { this.maskRef.updateOptions(maskOptions); // TODO fix if ('value' in props && props.value !== undefined) this.maskValue = props.value; } else { this.initMask(maskOptions); } } else { this.destroyMask(); if ('value' in props && props.value !== undefined) { if (((_a = this.element) === null || _a === void 0 ? void 0 : _a.isContentEditable) && this.element.tagName !== 'INPUT' && this.element.tagName !== 'TEXTAREA') this.element.textContent = props.value; else this.element.value = props.value; } } } componentWillUnmount() { this.destroyMask(); } _inputRef(el) { this.element = el; if (this.props.inputRef) { if (Object.prototype.hasOwnProperty.call(this.props.inputRef, 'current')) this.props.inputRef.current = el; else this.props.inputRef(el); } } initMask(maskOptions = this._extractMaskOptionsFromProps(this.props)) { this.maskRef = (0, imask_1.default)(this.element, maskOptions) .on('accept', this._onAccept.bind(this)) .on('complete', this._onComplete.bind(this)); if ('value' in this.props && this.props.value !== undefined) this.maskValue = this.props.value; } destroyMask() { if (this.maskRef) { this.maskRef.destroy(); delete this.maskRef; } } _extractMaskOptionsFromProps(props) { const { ...cloneProps } = props; // keep only mask options Object.keys(cloneProps) .filter(prop => MASK_OPTIONS_NAMES.indexOf(prop) < 0) .forEach(nonMaskProp => { delete cloneProps[nonMaskProp]; }); return cloneProps; } _extractNonMaskProps(props) { const { ...cloneProps } = props; MASK_PROPS_NAMES.forEach(maskProp => { if (maskProp !== 'maxLength') delete cloneProps[maskProp]; }); if (!('defaultValue' in cloneProps)) cloneProps.defaultValue = props.mask ? '' : cloneProps.value; delete cloneProps.value; return cloneProps; } get maskValue() { if (!this.maskRef) return ''; if (this.props.unmask === 'typed') return this.maskRef.typedValue; if (this.props.unmask) return this.maskRef.unmaskedValue; return this.maskRef.value; } set maskValue(value) { if (!this.maskRef) return; value = (value == null && this.props.unmask !== 'typed' ? '' : value); if (this.props.unmask === 'typed') this.maskRef.typedValue = value; else if (this.props.unmask) this.maskRef.unmaskedValue = value; else this.maskRef.value = value; } _onAccept(e) { if (this.props.onAccept && this.maskRef) this.props.onAccept(this.maskValue, this.maskRef, e); } _onComplete(e) { if (this.props.onComplete && this.maskRef) this.props.onComplete(this.maskValue, this.maskRef, e); } render() { return react_1.default.createElement(ComposedComponent, { ...this._extractNonMaskProps(this.props), inputRef: this._inputRef, }); } }; const nestedComponentName = ComposedComponent.displayName || ComposedComponent.name || 'Component'; MaskedComponent.displayName = `IMask(${nestedComponentName})`; MaskedComponent.propTypes = MASK_PROPS; return react_1.default.forwardRef( // @ts-ignore~ (props, ref) => react_1.default.createElement(MaskedComponent, { ...props, ref })); } //# sourceMappingURL=mixin.js.map