try-react-password-input
Version:
A password input with certain validations provided by the developer via props
388 lines (327 loc) • 16.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _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; };
var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _style = require('styled-jsx/style');
var _style2 = _interopRequireDefault(_style);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _passwordValidator = require('password-validator');
var _passwordValidator2 = _interopRequireDefault(_passwordValidator);
var _pickReactKnownProp = require('pick-react-known-prop');
var _lodash = require('lodash.map');
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = require('lodash.omit');
var _lodash4 = _interopRequireDefault(_lodash3);
var _lodash5 = require('lodash.pick');
var _lodash6 = _interopRequireDefault(_lodash5);
var _lodash7 = require('lodash.intersection');
var _lodash8 = _interopRequireDefault(_lodash7);
var _lodash9 = require('lodash.pickby');
var _lodash10 = _interopRequireDefault(_lodash9);
var _lodash11 = require('lodash.keys');
var _lodash12 = _interopRequireDefault(_lodash11);
var _lodash13 = require('lodash.isnull');
var _lodash14 = _interopRequireDefault(_lodash13);
var _lodash15 = require('lodash.isarray');
var _lodash16 = _interopRequireDefault(_lodash15);
var _lodash17 = require('lodash.replace');
var _lodash18 = _interopRequireDefault(_lodash17);
var _applyRules = require('./applyRules');
var _applyRules2 = _interopRequireDefault(_applyRules);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable react/no-unused-prop-types */
var isTrueOrNonZeroNumber = function isTrueOrNonZeroNumber(value) {
return value === true || value > 0;
};
var validations = ['uppercase', 'lowercase', 'min', 'max', 'digits', 'noSpaces', 'symbols'];
var getAvlblValidations = function getAvlblValidations(props) {
return (0, _lodash8.default)((0, _lodash12.default)((0, _lodash10.default)(props, isTrueOrNonZeroNumber)), validations);
};
var getEmptyPasswordValidity = function getEmptyPasswordValidity(props) {
return props.list ? getAvlblValidations(props) : null;
};
var validationMessages = function validationMessages(validation, quant) {
var messages = {
uppercase: 'Should contain atleast one uppercase letter',
lowercase: 'Should contain atleast one lowercase letter',
min: 'Should not be less than ' + quant + ' characters',
max: 'Should not be more than ' + quant + ' characters',
digits: 'Should contain atleast one numeric character',
noSpaces: 'Should not have spaces between characters',
symbols: 'Should have atleast one symbol'
};
return messages[validation];
};
// eslint-disable-next-line max-len
var eyeIconBase64 = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODIiIGhlaWdodD0iNTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxnPiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPiAgPHJlY3QgZmlsbD0ibm9uZSIgaWQ9ImNhbnZhc19iYWNrZ3JvdW5kIiBoZWlnaHQ9IjUyIiB3aWR0aD0iODQiIHk9Ii0xIiB4PSItMSIvPiA8L2c+IDxnPiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPiAgPGcgc3Ryb2tlPSJudWxsIiBpZD0ic3ZnXzEiPiAgIDxwYXRoIHN0cm9rZT0ibnVsbCIgaWQ9InN2Z18yIiBkPSJtNDEuOTI0OTk5LDEuMDI2OTg2Yy0xNS4yODE1NjIsMCAtMjkuMTM5NjgyLDguMzYwNjgzIC0zOS4zNjU1NjYsMjEuOTQwNjU5Yy0wLjgzNDQzMiwxLjExMjU3NiAtMC44MzQ0MzIsMi42NjY5MTEgMCwzLjc3OTQ4N2MxMC4yMjU4ODUsMTMuNTk2MzM3IDI0LjA4NDAwNCwyMS45NTcwMiAzOS4zNjU1NjYsMjEuOTU3MDJzMjkuMTM5NjgyLC04LjM2MDY4MyAzOS4zNjU1NjYsLTIxLjk0MDY1OWMwLjgzNDQzMiwtMS4xMTI1NzYgMC44MzQ0MzIsLTIuNjY2OTExIDAsLTMuNzc5NDg3Yy0xMC4yMjU4ODUsLTEzLjU5NjMzNyAtMjQuMDg0MDA0LC0yMS45NTcwMiAtMzkuMzY1NTY2LC0yMS45NTcwMnptMS4wOTYyMTUsNDAuNjI1Mzk1Yy0xMC4xNDQwNzgsMC42MzgwOTUgLTE4LjUyMTEyMywtNy43MjI1ODggLTE3Ljg4MzAyNywtMTcuODgzMDI3YzAuNTIzNTY1LC04LjM3NzA0NSA3LjMxMzU1MywtMTUuMTY3MDMyIDE1LjY5MDU5OCwtMTUuNjkwNTk4YzEwLjE0NDA3OCwtMC42MzgwOTUgMTguNTIxMTIzLDcuNzIyNTg4IDE3Ljg4MzAyNywxNy44ODMwMjdjLTAuNTM5OTI3LDguMzYwNjgzIC03LjMyOTkxNCwxNS4xNTA2NzEgLTE1LjY5MDU5OCwxNS42OTA1OTh6bS0wLjUwNzIwNCwtNy43NTUzMTFjLTUuNDY0NzEzLDAuMzQzNTkgLTkuOTgwNDY0LC00LjE1NTggLTkuNjIwNTEyLC05LjYyMDUxMmMwLjI3ODE0NCwtNC41MTU3NTEgMy45NDMxMDEsLTguMTY0MzQ2IDguNDU4ODUyLC04LjQ1ODg1MmM1LjQ2NDcxMywtMC4zNDM1OSA5Ljk4MDQ2NCw0LjE1NTggOS42MjA1MTIsOS42MjA1MTJjLTAuMjk0NTA1LDQuNTMyMTEyIC0zLjk1OTQ2Myw4LjE4MDcwOCAtOC40NTg4NTIsOC40NTg4NTJ6Ii8+ICA8L2c+IDwvZz48L3N2Zz4=';
var GreenTick = function GreenTick() {
return _react2.default.createElement(
'span',
{
'data-jsx': 647915208
},
_react2.default.createElement(_style2.default, {
styleId: 647915208,
css: 'span[data-jsx="647915208"]{color:green}'
}),
'\u2713'
);
};
var RedCross = function RedCross() {
return _react2.default.createElement(
'span',
{
'data-jsx': 1535297024
},
_react2.default.createElement(_style2.default, {
styleId: 1535297024,
css: 'span[data-jsx="1535297024"]{color:red}'
}),
'\u2716'
);
};
var Password = function (_Component) {
_inherits(Password, _Component);
function Password(props) {
_classCallCheck(this, Password);
var _this = _possibleConstructorReturn(this, (Password.__proto__ || Object.getPrototypeOf(Password)).call(this));
_this.state = {
passwordValidity: getEmptyPasswordValidity(props),
showPassword: false
};
_this.validation = new _passwordValidator2.default();
(0, _applyRules2.default)(_this.validation, (0, _lodash6.default)(props, validations));
// binding unbound methods
_this.handleChange = _this.handleChange.bind(_this);
_this.toggleShowPassword = _this.toggleShowPassword.bind(_this);
_this.assignPasswordInputRef = _this.assignPasswordInputRef.bind(_this);
return _this;
}
_createClass(Password, [{
key: 'assignPasswordInputRef',
value: function assignPasswordInputRef(ref) {
this.password = ref;
}
}, {
key: 'toggleShowPassword',
value: function toggleShowPassword() {
this.setState({
showPassword: !this.state.showPassword
});
}
}, {
key: 'handleChange',
value: function handleChange() {
var password = this.password.value;
var list = this.props.list;
var passwordValidity = password ? this.validation.validate(password, { list: list }) : getEmptyPasswordValidity(this.props);
var replaceWith = {
isMin: 'min',
isMax: 'max',
spaces: 'noSpaces'
};
var replaceIfNeedded = function replaceIfNeedded(validities) {
return (0, _lodash2.default)(validities, function (validity) {
return (0, _lodash18.default)(validity, /isMax|isMin|spaces/, function (pat) {
return replaceWith[pat];
});
});
};
this.setState({
passwordValidity: (0, _lodash16.default)(passwordValidity) ? replaceIfNeedded(passwordValidity) : passwordValidity
});
this.props.onChange(passwordValidity, password);
}
}, {
key: 'renderPasswordValidityWithoutList',
value: function renderPasswordValidityWithoutList() {
return _react2.default.createElement(
'div',
{ className: 'password-validity list-less', 'data-jsx': 596452250
},
_react2.default.createElement(_style2.default, {
styleId: 596452250,
css: '.password-validity.list-less[data-jsx="596452250"]{height:25px;width:25px;float:left;padding:3px 0;-webkit-text-align:center;text-align:center}'
}),
!(0, _lodash14.default)(this.state.passwordValidity) && (this.state.passwordValidity ? _react2.default.createElement(GreenTick, null) : _react2.default.createElement(RedCross, null))
);
}
}, {
key: 'renderPasswordValidityWithList',
value: function renderPasswordValidityWithList() {
var _this2 = this;
var passwordValidity = this.state.passwordValidity;
var renderValidity = function renderValidity(validation) {
return _react2.default.createElement(
'li',
{ key: validation, 'data-jsx': 2553595392
},
_react2.default.createElement(_style2.default, {
styleId: 2553595392,
css: 'li[data-jsx="2553595392"]{list-style-type:none}'
}),
passwordValidity.indexOf(validation) === -1 ? _react2.default.createElement(GreenTick, null) : _react2.default.createElement(RedCross, null),
_react2.default.createElement(
'span',
{
'data-jsx': 2553595392
},
validationMessages(validation, validation === 'min' ? _this2.props.min : _this2.props.max)
)
);
};
var availableValidations = getAvlblValidations(this.props);
return _react2.default.createElement(
'div',
{ className: 'password-validity list', 'data-jsx': 2137515968
},
_react2.default.createElement(_style2.default, {
styleId: 2137515968,
css: '.password-validity.list[data-jsx="2137515968"]{position:absolute;visibility:hidden;background-color:rgba(0, 0, 0, 0.2);border:1px solid #000;border-radius:4px;margin-left:15px;margin-top:30px;max-width:calc(100% - 15px);box-sizing:border-box}.password-validity.list[data-jsx="2137515968"] ul[data-jsx="2137515968"]{padding:0 10px;margin:10px 0}'
}),
_react2.default.createElement(
'ul',
{
'data-jsx': 2137515968
},
(0, _lodash2.default)(availableValidations, renderValidity)
)
);
}
}, {
key: 'renderShowPasswordBtn',
value: function renderShowPasswordBtn() {
var showPasswordClass = this.state.showPassword ? 'on' : 'off';
return _react2.default.createElement(
'div',
{ className: showPasswordClass + ' show-password', 'data-jsx': 1717931011
},
_react2.default.createElement(_style2.default, {
styleId: 1717931011,
css: '.show-password[data-jsx="1717931011"]{height:25px;width:25px;display:inline-block}.show-password.on[data-jsx="1717931011"]{opacity:0.8}.show-password.off[data-jsx="1717931011"]{opacity:0.2}.show-password[data-jsx="1717931011"] button[data-jsx="1717931011"]{height:100%;width:100%;box-sizing:border-box;background-image:url(' + eyeIconBase64 + ');background-repeat:no-repeat;background-position:center center;background-size:contain;background-color:transparent;border:none;outline:none;cursor:pointer}'
}),
_react2.default.createElement('button', { onClick: this.toggleShowPassword, 'data-jsx': 1717931011
})
);
}
}, {
key: 'render',
value: function render() {
var omittedProps = ['onChange', 'value', 'defaultValue', 'type', 'min', 'max', 'className'];
var _props = this.props,
showPassword = _props.showPassword,
showValidity = _props.showValidity,
list = _props.list;
var widthClass = showPassword ? 'with-show-password' : 'without-show-password';
var validityClass = showValidity && !list ? 'show-validity' : 'hide-validity';
return _react2.default.createElement(
'div',
{ className: this.props.className + ' ' + widthClass + ' ' + validityClass + ' password-input', 'data-jsx': 780010005
},
_react2.default.createElement('input', _extends({
type: this.state.showPassword ? 'text' : 'password',
ref: this.assignPasswordInputRef,
defaultValue: this.props.value,
onChange: this.handleChange,
className: this.props.inputClass + ' input'
}, (0, _pickReactKnownProp.pickHTMLProps)((0, _lodash4.default)(this.props, omittedProps)), {
'data-jsx': 780010005
})),
showValidity && !list ? this.renderPasswordValidityWithoutList() : null,
this.props.showPassword ? this.renderShowPasswordBtn() : null,
showValidity && list ? this.renderPasswordValidityWithList() : null,
_react2.default.createElement(_style2.default, {
styleId: 509473068,
css: '.password-input[data-jsx="780010005"]{display:inline-block;border:1px solid;height:27px;box-sizing:border-box;display:inherit;border-radius:4px;overflow:hidden;padding-right:2px}.password-input[data-jsx="780010005"] input[data-jsx="780010005"]{float:left;box-sizing:border-box;height:25px;border:1px solid;border:none;outline:none;padding-left:2px}.with-show-password.hide-validity[data-jsx="780010005"] input[data-jsx="780010005"],.without-show-password.show-validity[data-jsx="780010005"] input[data-jsx="780010005"]{width:calc(100% - 25px)}.with-show-password.show-validity[data-jsx="780010005"] input[data-jsx="780010005"]{width:calc(100% - 25px - 25px)}.without-show-password.hide-validity[data-jsx="780010005"] input[data-jsx="780010005"]{width:100%}'
}),
_react2.default.createElement(_style2.default, {
styleId: 1979381500,
css: '.password-input input:focus~.password-validity.list{visibility:visible}'
})
);
}
}]);
return Password;
}(_react.Component);
Password.propTypes = {
/**
* value of password text
*/
value: _propTypes2.default.string,
/**
* method called everytime value is changed in text
*/
onChange: _propTypes2.default.func,
/**
* specifies whether password should contain atleast one uppercase characters
*/
uppercase: _propTypes2.default.bool,
/**
* specifies whether password should contain atleast one lowercase chars
*/
lowercase: _propTypes2.default.bool,
/**
* specifies that password should contain digits
*/
digits: _propTypes2.default.bool,
/**
* specifies that password should not contain any spaces
*/
noSpaces: _propTypes2.default.bool,
/**
* specifies the maximum number characters in password
* no max chars in password, unless specified
*/
max: _propTypes2.default.number, // eslint-disable-line react/require-default-props
/**
* specifies the minimum number characters in password
* no min chars in password, unless specified
*/
min: _propTypes2.default.number, // eslint-disable-line react/require-default-props
/**
* specifies whether or not password should contain symbols
*/
symbols: _propTypes2.default.bool,
/**
* specfies whether to return list of failed validations or only if they have failed or not
*/
list: _propTypes2.default.bool,
/**
* specifies whether password validity needs to be shown or not
*/
showValidity: _propTypes2.default.bool,
/**
* display `show password` button
*/
showPassword: _propTypes2.default.bool,
/**
* append class to input element
*/
inputClass: _propTypes2.default.string,
/**
* gives the className to the root element
*/
className: _propTypes2.default.string
};
Password.defaultProps = {
value: '',
onChange: function onChange() {},
noSpaces: false,
uppercase: false,
lowercase: false,
digits: false,
symbols: false,
list: true,
showValidity: true,
className: '',
inputClass: '',
showPassword: false
};
exports.default = Password;