1 import { Options, passwordStrength } from "check-password-strength";
2 import classNames from "classnames";
3 import { NoOptionI18nKeys } from "i18next";
4 import { Component, FormEventHandler, linkEvent } from "inferno";
5 import { NavLink } from "inferno-router";
6 import { I18NextService } from "../../services";
7 import { Icon } from "./icon";
9 interface PasswordInputProps {
12 onInput: FormEventHandler<HTMLInputElement>;
14 showStrength?: boolean;
15 label?: string | null;
16 showForgotLink?: boolean;
20 interface PasswordInputState {
24 const passwordStrengthOptions: Options<string> = [
51 function handleToggleShow(i: PasswordInput) {
58 class PasswordInput extends Component<PasswordInputProps, PasswordInputState> {
59 state: PasswordInputState = {
63 constructor(props: PasswordInputProps, context: any) {
64 super(props, context);
84 <div className={classNames("row", className)}>
86 <label className="col-sm-2 col-form-label" htmlFor={id}>
90 <div className={`col-sm-${label ? 10 : 12}`}>
91 <div className="input-group">
93 type={show ? "text" : "password"}
94 className="form-control"
96 autoComplete={isNew ? "new-password" : "current-password"}
104 className="btn btn-outline-dark"
107 onClick={linkEvent(this, handleToggleShow)}
108 aria-label={I18NextService.i18n.t(
109 `${show ? "show" : "hide"}_password`,
111 data-tippy-content={I18NextService.i18n.t(
112 `${show ? "show" : "hide"}_password`,
115 <Icon icon={`eye${show ? "-slash" : ""}`} inline />
118 {showStrength && value && (
119 <div className={this.passwordColorClass}>
120 {I18NextService.i18n.t(
121 this.passwordStrength as NoOptionI18nKeys,
127 className="btn p-0 btn-link d-inline-block float-right text-muted small font-weight-bold pointer-events not-allowed"
130 {I18NextService.i18n.t("forgot_password")}
139 get passwordStrength(): string | undefined {
140 const password = this.props.value;
142 ? passwordStrength(password, passwordStrengthOptions).value
146 get passwordColorClass(): string {
147 const strength = this.passwordStrength;
149 if (strength && ["weak", "medium"].includes(strength)) {
150 return "text-warning";
151 } else if (strength === "strong") {
152 return "text-success";
154 return "text-danger";
159 export default PasswordInput;